The Java 21 specification states
A reference to a static field (§8.3.1.1) causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.
and later
A class or interface will not be initialized under any other circumstance.
But when I have the following classes
public class Base {
static {
System.out.println("Base");
}
}
public class Derived extends Base {
static {
System.out.println("Derived");
}
public static int foo = 2;
}
public class Main {
public static void main(String[] args) {
System.out.println(Derived.foo);
}
}
The output of the program is
Base
Derived
2
It seems to me that the class Base is initialized. Why is this the case? Doesn’t the specification forbid this?
>Solution :
You are perhaps misunderstanding what "initialization of only the class or interface that actually declares it" means.
Consider this modification to your code:
public class Base { ... }
public class Derived extends Base { ... }
public class Derived2 extends Derived {
static {
System.out.println("Derived2");
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Derived2.foo);
}
}
If you run this (Ideone), you will find it outputs:
Base
Derived
2
i.e. it doesn’t print Derived2.
In order to initialize a class, you have to initialize its superclasses. From JLS 12.4:
When a class is initialized, its superclasses are initialized (if they have not been previously initialized)
but Java doesn’t need to initialize Derived2 in order to print a static symbol from Derived.