类初始化规则声明: 如果由于访问静态字段而触发了类初始化,则只有已声明静态字段的Class才会被初始化,并且它不会触发超类或子类的初始化,即使静态字段由子类,子接口类型或通过接口的实现类。 然后在下面的代码中,只应打印“Initializing Superclass”。
Superclass.java :
public class Superclass {
public static long INIT_TIME = System.currentTimeMillis();
static {
System.out.println("Initializing Superclass");
}
}
Subclass.java:
public class Subclass extends Superclass {
static {
System.out.println("Initializing Subclass");
}
}
public static void main(String[] args) {
long time = Subclass.INIT_TIME;
}
}
当我运行它时,输出:
Initializing Superclass
Initializing Subclass
答案 0 :(得分:2)
请参阅第12.1.3章中的Java Language Specification。
规则是: “如果Class Test有另一个类Super作为它的超类,那么Super必须在Test之前初始化。”
子类未初始化,但超类是。
答案 1 :(得分:0)
您的代码很可能是这样的:
public class Temp extends SuperTemp { // subclass
static {
System.out.println("Initializing Temp");
}
}
class SuperTemp { // super class
static int i = 0;
static {
System.out.println("Initializing SuperTemp");
}
}
class SomeOtherClass {
public static void main(String[] args) {
System.out.println(Temp.i); // from some other class you are calling SubClass.superClassField
}
}
O / P:
Initializing SuperTemp
0
原因:在运行期间{J}将Temp.i
解析为SuperTemp.i
。因此,Temp
将加载,但已初始化。查看类的加载方式:
java -verbose:class
[Loaded SomeOtherClass from file XXXX]
[Loaded SuperTemp from file XXXX]
[Loaded Temp from file XXXX]
Initializing SuperTemp
0
答案 2 :(得分:0)
正如你所说: -
如果由于访问静态字段而触发了类初始化,则只有已声明静态字段的Class被初始化并且它不会触发超类或子类的初始化,即使静态字段由子类类型Sub引用也是如此接口或接口的实现类
这清楚地表明输出应仅为Initializing Superclass
。
我运行你的程序并将输出作为
初始化超类
1414998665110
如果您按照提到的那样获得输出,那么您在问题中没有说明其他内容。
注意: - 参考Jon Skeet就此question提供的答案,似乎该文章的一部分错误地说: -
如果由于访问静态字段而触发了类初始化,则只会初始化已声明静态字段的Class,并且不会触发超类的初始化
这与您的情况无关,因为INIT_TIME
是Superclass
的一部分,因此当您说SuperClass_object.INIT_TIME
时,您基本上是在撰写subclass.INIT_TIME
。如果您的INIT_TIME
而不是Subclass
中有Superclass
字段,则会输出: -
初始化超类
初始化子类
1414998665110
总结这意味着Superclass gets intialized even if Class initialization is triggered due to access of static field, But Subclass is not initialized.