When the static block will be executed in JAVA while creating object?

class DemoClass {
    public static void main(String args[]) {
        System.out.println("Start");
        A a=new D();
    }
}
class A {
    static {
        System.out.println("Static A");
        A c=new C();
    }

    public A() {
        System.out.println("Constr A");
    }
}

class B extends A {
    static {
        System.out.println("Static B"); 
    }

    public B() {
        System.out.println("Constr B");
    }
}

class C extends B {
    static {
        System.out.println("Static C");
    }

    public C() {
        System.out.println("Constr C");
    }
}

class D extends C {
    static {
        System.out.println("Static D");
    }

    public D() {
        System.out.println("Constr D");
    }
}

The order of execution for above code is:

Start
Static A
Constr A
Constr B
Constr C
Static B
Static C
Static D
Constr A
Constr B
Constr C
Constr D

In my view all the static blocks should be executed first then only the object will be created. But, here the object "A c=new C()" in class A static block is created first and then the other static blocks are executed. Why?

Jon Skeet
people
quotationmark

The static initializer of all the classes have started executing - but in order to initialize D, C must be initialized, so B must be initialized, so A must be initialized. At the point where the code in the static initializer in A is being executed, all of the classes involved are in a state of "being initialized".

Within the static initializer of A, it constructs an instance of C - but C is already being initialized, so the initializer doesn't start again... the JVM just notes that it's already being initialized (within the same thread) and continues.

The details of all of this are in JLS 12.4.2. In particular, the bullet:

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.

and

Next, if C is a class rather than an interface, and its superclass has not yet been initialized, then let SC be its superclass and let SI1, ..., SIn be all superinterfaces of C that declare at least one default method. [...]

For each S in the list [ SC, SI1, ..., SIn ], recursively perform this entire procedure for S. If necessary, verify and prepare S first.

... are relevant.

people

See more on this question at Stackoverflow