Ayusman
Ayusman

Reputation: 8729

How JVM loads a class that has it's own reference

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

Answers (4)

Peter Lawrey
Peter Lawrey

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

Marko Topolnik
Marko Topolnik

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

Suresh Atta
Suresh Atta

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

Lasse Meyer
Lasse Meyer

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

Related Questions