假设 JVM 第一次加载了以下Foo
类,它刚刚传递给链接步骤(在解析期间)。
public static void main(...) {
new Foo();
}
public class Foo {
private static int a = 4;
private static Hoo hoo = new Hoo();
Foo (){
Log.i("Test", ">> Test foo's created!");
}
}
public class Hoo {
private static int b = 4;
private static Soo soo = new Soo();
Hoo (){
Log.i("Test", ">> Test hoo's created!");
}
}
public class Soo {
private static int b = 4;
private static Koo soo = new Koo();
Soo (){
Log.i("Test", ">> Test soo's created!");
}
}
...
现在我的问题是这个。我们知道在完成子类构造之前,系统调用递归的基类/超类构造函数。上面的代码中是否存在一些类似的逻辑?我的意思是 JVM 在完成Foo
和Hoo()
构建后会立即完成Soo()
的构建吗?
THX。
答案 0 :(得分:3)
我的意思是JVM在完成Hoo()和Soo()构建后会立即完成Foo的构建吗?
基本上......是的。
根据JLS 12.4.1:
类或接口类型T将在第一次出现以下任何一个之前立即初始化:
T是一个类,并创建了一个T实例。
调用T声明的静态方法。
分配由T声明的静态字段。
使用T声明的静态字段,该字段不是常量变量(§4.12.4)。
T是顶级类(第7.6节),并且执行在词典内嵌套在T(第8.1.3节)内的断言语句(第14.10节)。
等等。
在您的示例中,这意味着将按照Koo
,Soo
,Hoo
,Foo
的顺序初始化类,并执行new Foo()
main
方法中的表达式将触发此操作。
如果不同类的静态初始化之间存在循环依赖关系,那么事情会变得有点复杂(并且讨厌),但JLS也涵盖了这种边缘情况。