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?
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 forC
indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. ReleaseLC
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.
See more on this question at Stackoverflow