【发布时间】:2011-01-01 17:38:24
【问题描述】:
假设一个项目包含多个类,每个类都有一个静态初始化块。这些块以什么顺序运行?我知道在一个类中,这些块按照它们在代码中出现的顺序运行。我读过它在各个类中都是一样的,但是我写的一些示例代码不同意这一点。我使用了这段代码:
package pkg;
public class LoadTest {
public static void main(String[] args) {
System.out.println("START");
new Child();
System.out.println("END");
}
}
class Parent extends Grandparent {
// Instance init block
{
System.out.println("instance - parent");
}
// Constructor
public Parent() {
System.out.println("constructor - parent");
}
// Static init block
static {
System.out.println("static - parent");
}
}
class Grandparent {
// Static init block
static {
System.out.println("static - grandparent");
}
// Instance init block
{
System.out.println("instance - grandparent");
}
// Constructor
public Grandparent() {
System.out.println("constructor - grandparent");
}
}
class Child extends Parent {
// Constructor
public Child() {
System.out.println("constructor - child");
}
// Static init block
static {
System.out.println("static - child");
}
// Instance init block
{
System.out.println("instance - child");
}
}
得到这个输出:
开始
静态 - 祖父母
静态 - 父
静态 - 孩子
实例 - 祖父母
构造函数 - 祖父母
实例 - 父
构造函数 - 父
实例 - 子
构造函数 - 子
结束
显而易见的答案是父母的积木在他们孩子的之前运行,但这可能只是巧合,如果两个类不在同一个层次结构中,则无济于事。
编辑:
我通过将它附加到 LoadTest.java 来修改我的示例代码:
class IAmAClassThatIsNeverUsed {
// Constructor
public IAmAClassThatIsNeverUsed() {
System.out.println("constructor - IAACTINU");
}
// Instance init block
{
System.out.println("instance - IAACTINU");
}
// Static init block
static {
System.out.println("static - IAACTINU");
}
}
正如类名所暗示的那样,我从未在任何地方引用过新类。新程序产生的输出与旧程序相同。
【问题讨论】:
-
这里的一大启示是父构造函数将在子实例初始化程序之前执行!