From JLS 12.4.1:
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, and an assert statement (§14.10) lexically nested within T is executed.
As you can see, nothing of these happens in your code (note that name
is declared in Parent
, not in Child
), therefore Child
doesn't get initialized and its static block doesn't get executed.
If you do something to trigger initialization of Child
, you'll get an expected output:
new Child();
System.out.println(Child.name);
Note, however, that static fields are not inherited, therefore Child.name
and Parent.name
actually refer to the same field. That's why it doesn't make much sense to use code similar to your example in practice.
Also note that despite the fact that Child.name
actually refers to Parent.name
, it's still referenced as Child.name
in the bytecode, therefore your code triggers loading of Child
, but not its initialization.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…