问题
I am preparing myself for Java certification test and I have found an interesting question related to the execution of Java static blocks. I have spent a lot of time reading about this topic, but I didn't find the answer I was looking for.
I know that static blocks are executed when the class is loaded into JVM or when the main method is invoked, but...
package oneClassTasks;
class Parent {
static int age;
}
class Child extends Parent {
static {
age = 5;
System.out.println("child's static block");
}
}
public class XXX {
public static void main(String args[]) {
System.out.println("Child age is : "+ Child.age);
}
}
The output is:
Child age is : 0
If I include verbose output with -verbose:class
, then the output is:
...
[Loaded java.security.BasicPermissionCollection from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded oneClassTasks.XXX from file:/D:/temp/bin/]
[Loaded sun.launcher.LauncherHelper$FXHelper from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded java.lang.Class$MethodArray from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded java.lang.Void from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded oneClassTasks.Parent from file:/D:/temp/bin/]
[Loaded oneClassTasks.Child from file:/D:/temp/bin/]
Child age is : 0
[Loaded java.lang.Shutdown from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
We can see here that Child class is loaded into JVM.
Can someone explain why the static block from Child
class is not executed?
回答1:
You saw that Child
class was loaded, but it wasn't initialized.
Accessing Child.age
doesn't cause the initialization of the Child
class, since age
is a member of Parent
class. Therefore only Parent
class is initialized, and age
remains 0
.
12.4.1. When Initialization Occurs
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.
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.
In your case you accessed a static field declared by Parent
, so only Parent
is initialized.
回答2:
In this case, Child.age is equivalent to Parent.age. JRE will treat it as Parent.age, that's why only Parent is statically initialized, and Child's static initializer is skipped.
来源:https://stackoverflow.com/questions/48989134/execution-of-java-static-blocks-in-subclasses