当我遇到这个例子时,我正在练习Java考试:
class A1 {
static {
System.out.println("A1S");
}
public static void main(String args[]) {
new A3();
}
}
class A2 {
static {
System.out.println("A2S");
}
public A2() {
System.out.println("A2");
}
static A3 as = new A3();
}
class A3 extends A2 {
static {
System.out.println("A3S");
}
public A3() {
System.out.println("A3");
}
}
class A4 extends A3 {
public A4() {
super();
System.out.println("A4");
}
}
我期待以下输出:
A1S
A2S
A3S
A2
A3
A2
A3
但我收到了这个输出:
A1S
A2S
A2
A3
A3S
A2
A3
在构造函数输出之前,不应该执行A3中的静态块吗? JavaDoc说:
类的初始化包括执行其静态初始化程序和类中声明的静态字段(类变量)的初始化程序。 类或接口类型T将在之前立即初始化 第一次出现以下任何一种情况:
T是一个类,并创建了T的实例。
T是一个类,由T声明的静态方法是 调用
分配由T声明的静态字段。
使用T声明的静态字段,该字段不是常量 变量(§4.12.4)。
T是顶级类(第7.6节)和断言语句(第14.10节) 在词典中嵌套在T(§8.1.3)中执行。
对静态字段的引用(第8.3.1.1节)仅导致实际声明它的类或接口的初始化,即使它可能通过子类的名称,子接口或实现的类来引用界面