从JLS
12.4.1开始:
类或接口类型T将在以下任何一种首次出现之前立即初始化:
- T是一个类,并创建T的实例。
- T是一个类,并调用T声明的静态方法。
- 分配由T声明的静态字段。
- 使用由T声明的静态字段,并且该字段不是常量变量(第4.12.4节)。
- T是一个顶级类,并执行词法嵌套在T中的assert语句(第14.10节)。
如您所见,这些都不会在您的代码中发生任何变化(请注意,该
name声明是在
Parent中而不是在中声明的
Child),因此
Child不会被初始化,并且其静态块也不会被执行。
如果您执行一些操作来触发的初始化
Child,则会得到预期的输出:
new Child();System.out.println(Child.name);
但是请注意,该静态字段不能被继承,因此
Child.name和
Parent.name实际指的是同一领域。这就是为什么在实践中使用类似于您的示例的代码没有多大意义。
还要注意,尽管实际上
Child.name实际上指的是
Parent.name,但它仍然
Child.name在字节码中被引用,因此您的代码触发的加载
Child,但不会触发其初始化。



