6

Code:

class A {
    static {
        System.out.println("loading A static 1");
    }
    static {
        System.out.println("loading A static 2 B.c= "+B.c);        
    }
    static {
        System.out.println("loading static 3");
    }
    static int a=10; 
    A(){        
    }
}

class B extends A{
    static {
       System.out.println("loading B A.a= "+A.a);
    }
    static int c = 50;
}
public class Test {
    public static void main(String[] args) {
        new B();
    }
}

Output:

loading A static 1
loading A static 2 B.c= 0
loading static 3
loading B A.a= 10

From this out put can we say that the parent class loads after the child class but child class initialize after the parent class? If so how JVM loads class hierarchies?

P̲̳x͓L̳
  • 3,615
  • 3
  • 29
  • 37
Kalhan.Toress
  • 21,683
  • 8
  • 68
  • 92
  • An related question: [jvm - Why does "Inside the Java Virtual Machine" say "NewbornBaby need not be loaded"? - Stack Overflow](https://stackoverflow.com/questions/63756025/why-does-inside-the-java-virtual-machine-say-newbornbaby-need-not-be-loaded). – Jason Law Sep 07 '20 at 01:27

3 Answers3

9

The Java Language Specification explains the process of initializing a class.

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.

  • T is a class and a static method declared by T is invoked.

  • A static field declared by T is assigned.

  • A static field declared by T is used and the field is not a constant variable (§4.12.4).

  • T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

and with more details

[...]

Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.

[...]

If the Class object for C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.

[...]

Next, if C is a class rather than an interface, and its superclass SC has not yet been initialized, then recursively perform this entire procedure for SC. If necessary, verify and prepare SC first. If the initialization of SC completes abruptly because of a thrown exception, then acquire LC, label the Class object for C as erroneous, notify all waiting threads, release LC, and complete abruptly, throwing the same exception that resulted from initializing SC.

So

new B();

requires that class B be initialized. Because B is a sub class of A, A needs to be initialized. While initializing A, this

static {
    System.out.println("loading A static 2 B.c= "+B.c);        
}

indicates that B needs to be initialized, but B is already in the process of being initialized, so it is ignored for now and A initialization continues. Because B's initialization is not complete, the field c has not yet been initialized to 50, so it prints 0.

A initializing completes. B initializing continues. B initializing completes and Boom! you're done.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
5

You can check this by executing it with java -verbose Test:

...
[Loaded A from file:/.../src/main/java/]
[Loaded B from file:/.../src/main/java/]
loading A static 1
loading A static 2 B.c= 0
loading static 3
loading B A.a= 10
...

So no, the parent class is loaded first too.

Keppil
  • 45,603
  • 8
  • 97
  • 119
  • 1
    so why in the second line of the output gives B.c=0 if class B is not loaded how B.c=0 came ? thank you – Kalhan.Toress Apr 01 '14 at 04:58
  • 1
    At that point both classes are loaded as you can see from the output. `B.c` is not initialized yet though, so it is still `0`. I think the output shows the order of everything very clearly. – Keppil Apr 01 '14 at 05:11
  • 1
    oh got it :) thank you, can you please tell me how JVM knows about class hierarchy ? – Kalhan.Toress Apr 01 '14 at 05:26
  • I'm not sure what you mean, could you please clarify a little? You specify in your code that `A` is the superclass of `B`, and `Object` is always the superclass of everything, so I think it is pretty well defined. – Keppil Apr 01 '14 at 05:34
  • 1
    what i asked is if we are going to create a Object of B the parent class A will load first. so how JVM solve the super class of B is A ? – Kalhan.Toress Apr 01 '14 at 05:37
  • You have defined it in the class definition of `B`, so the JVM just has to look there. – Keppil Apr 01 '14 at 05:44
  • @Keppil The parent class is not loaded at first, it is that *JVM completes the loading of the parent class at first*. Holger explains [here](https://stackoverflow.com/a/63763771/5232255). – Jason Law Sep 07 '20 at 01:26
1

the static block will be executed when a class is initialized. and we know

Before a class is initialized, its direct superclass must be initialized,

So in your case when you are initializing the B it's superclass is automatically initialized before that.

for details you can check this part of spec

stinepike
  • 54,068
  • 14
  • 92
  • 112