Reputation: 8729
Consider the following code snippet:
public class ListNode
{
ListNode nextNode;
//Constructors follow ...
//Member methods follow ...
}
I don't know much about the internals of classloading, to me it looks like loading (Because class can never be created) will never complete because ListNode will keep trying to find the ListNode class, is it not?
However this being one of the fundamentals of many data structures (LinkedList for example). It's obvious that it works.
So, how JVM interprets such a class definition and what is such references called in technical terms?
Upvotes: 2
Views: 93
Reputation: 533870
It is possible to achieve what you suggest but it's not as easy as it sounds. A class can only be initialised in one thread and it can't accessed by another thread until this completes.
public class Main {
static class Deadlock {
static int NUM = 1;
static {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// tries to use NUM in a new thread
System.out.println(NUM);
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
throw new AssertionError(e);
}
}
}
public static void main(String[] args) {
System.out.println("About to dead lock");
new Deadlock();
System.out.println(".. never gets here");
}
}
if you take a stack trace you see
"Thread-0" #11 prio=5 os_prio=0 tid=0x00007f9c2414a800 nid=0x2188 in Object.wait() [0x00007f9be983b000]
java.lang.Thread.State: RUNNABLE
at Main$Deadlock$1.run(Main.java:14)
at java.lang.Thread.run(Thread.java:745)
"main" #1 prio=5 os_prio=0 tid=0x00007f9c2400a000 nid=0x2163 in Object.wait() [0x00007f9c2caf0000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000fec64ec0> (a java.lang.Thread)
at java.lang.Thread.join(Thread.java:1245)
- locked <0x00000000fec64ec0> (a java.lang.Thread)
at java.lang.Thread.join(Thread.java:1319)
at Main$Deadlock.<clinit>(Main.java:19)
at Main.main(Main.java:28)
The main thread is waiting on the background thread to finish, however it can't get the value of NUM because the class hasn't finished initialising.
Upvotes: 2
Reputation: 200296
Your class definition simply contains a field declaration whose type is the class itself. It doesn't attempt to create an instance of the class. This poses no problem because the types of fields aren't even resolved when the class is being initialized. For example, your field could even be of a type unknown to the runtime, but you wouldn't get a NoClassDefFoundError
. By specification, you will get that error only when you actually refer to the type by trying to instantiate it, downcast into it, call a method with it in the signature, etc.
Upvotes: 1
Reputation: 122026
Points to remember
1) The term itself wrong, you need to term it as class instantiation.
2) If you are thinking a class instantiation itself, the technical term is recursion
and after sometime you run into stackoverlow
error.
3)your code
public class ListNode
{
ListNode nextNode;
//Constructors follow ...
//Member methods follow ...
}
is won't cause any stack overflow since you are not instantiating it, just declared it.
4)The below code
public class ListNode
{
ListNode nextNode = new ListNode();
//Constructors follow ...
//Member methods follow ...
}
is stackoverflow since it instantiating itself .
Upvotes: 1
Reputation: 1479
The class itself is only loaded once. You're probably mistaking class for object. But even with objects, since the reference is empty (you're just declaring the variable, but not assigning anything), there is no problem.
Upvotes: 2