正如某些消息来源所说,Java实例初始化块在创建实例时或在构造函数之前立即执行。但是想象一下这种情况:
public class Foo { { System.out.println("Foo init"); } public Foo() { { System.out.println("Foo constr"); } } } public class Main extends Foo { { System.out.println("Main init"); } public Main() { { System.out.println("Main constr"); } } public static void main(String[] args) { new Main(); } }
输出是(如预期的那样):
Foo init Foo constr Main init Main constr
所以我的问题是-实例初始化块的正确定义是什么,因为它显然没有在构造函数之前执行,因为输出应该是
Main init Foo init Foo constr Main constr
因为Main()构造函数是在调用super()之前调用的,所以Main初始化块应该是第一个。
不会。初始化块直接复制到构造函数中。显然那里也有一个隐式的超级。所以你的例子变成
public class Foo { public Foo() { {System.out.println("Foo init");} // initializer. {System.out.println("Foo constr");} } } public class Main extends Foo { public Main() { super(); // super constructor. {System.out.println("Main init");} // initializer. {System.out.println("Main constr");} } public static void main(String[] args) { new Main(); } }
这解释了您观察到的行为