Java中的静态/实例初始化块按照什么顺序运行?假设一个项目包含几个类,每个类都有一个静态初始化块。这些块按什么顺序运行?我知道,在类中,这样的块是按照它们在代码中出现的顺序运行的。我读过不同的类都是一样的,但是我编写的一些示例代码不同意这一点。我使用了这个代码: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");
}}正如类名所暗示的那样,我从未在任何地方引用过新类。新程序产生了与旧程序相同的输出。
3 回答
摇曳的蔷薇
TA贡献1793条经验 获得超6个赞
静态init块按照初始化类的顺序运行。
类或接口类型T将在第一次出现以下情况之前立即初始化:
T是一个类,并创建了一个T的实例。 T是一个类,调用T声明的静态方法。 指定一个由T声明的静态字段。 使用由T声明的静态字段,且该字段不是常量变量(§4.12.4)。 T是一个顶级类,在T中执行一个按词法嵌套的断言语句(§14.10)。
类和包中某些反射方法的调用还会导致类或接口初始化。在任何其他情况下都不会初始化类或接口。
进入主 打印“开始” 尝试创建第一个需要初始化子实例的实例
尝试初始化子节点会导致父级初始化
尝试初始化父级会导致祖父母的初始化。
在祖父母初始化开始时,运行祖父母的静态初始化块
从技术上讲,Object在初始化链中获得了最后的发言权,因为它是祖父母的父级,但是它没有什么可贡献的。
在祖父母的静态初始化块结束后,程序回到父程序的静态初始化块
在父程序的静态初始化块结束后,程序返回到child的静态初始化块
此时,初始化了child,因此它的构造函数可以继续
由于IAmAClassThatIsNeverUsed从未被引用过,因此它的任何代码都不会运行,包括静态初始化程序块。
本演练的其余部分与静态初始化器无关,仅为完整性而包含 子构造函数隐式调用Super()(即父构造函数) 父构造函数隐式调用Super()(即祖父母的构造函数) 祖父母的构造函数也是这样,没有任何效果(同样,对象没有任何贡献) 在祖父母的构造函数调用Super()之后,爷爷奶奶的实例初始化程序块立即出现 爷爷奶奶的构造函数的其余部分运行,构造函数终止 程序返回到父构造函数,在调用Super()(即祖父母的构造函数)后立即解析 如前所述,父实例初始化程序完成了它的工作,它的构造函数也完成了。 类似地,程序返回并完成child的构造函数 此时,对象已被实例化。 打印“结束” 正常终止
添加回答
举报
0/150
提交
取消