在Java中运行构造函数代码之前,字段是否已初始化?
任何人都可以解释下面的程序的输出吗? 我认为构造函数在实例变量之前被初始化。 所以我期待输出是“XZYY”。
class X {
Y b = new Y();
X() {
System.out.print("X");
}
}
class Y {
Y() {
System.out.print("Y");
}
}
public class Z extends X {
Y y = new Y();
Z() {
System.out.print("Z");
}
public static void main(String[] args) {
new Z();
}
}
正确的初始化顺序是:
请参阅Java虚拟机规范的§2.17.5-6部分。
如果您查看类文件的反编译版本
class X {
Y b;
X() {
b = new Y();
System.out.print("X");
}
}
class Y {
Y() {
System.out.print("Y");
}
}
public class Z extends X {
Y y;
Z() {
y = new Y();
System.out.print("Z");
}
public static void main(String args[]) {
new Z();
}
}
你可以发现实例变量y
被移入构造函数内部,所以执行顺序如下
Z
的构造函数 X
的默认构造函数 X
构造函数new Y()
第一行被调用。 new Y()
的第一行 Y
所有实例变量都使用构造函数语句进行初始化。
为了澄清静态的误解 - 我将简单地引用这一小段代码:
public class Foo {
{ System.out.println("Instance Block 1"); }
static { System.out.println("Static Block 1"); }
public static final Foo FOO = new Foo();
{ System.out.println("Instance Block 2"); }
static { System.out.println("Static Block 2 (Weird!!)"); }
public Foo() { System.out.println("Constructor"); }
static public void main(String p[]) {
System.out.println("In Main");
new Foo();
}
}
惊喜是输出如下:
Static Block 1
Instance Block 1
Instance Block 2
Constructor
Static Block 2 (Weird!!)
In Main
Instance Block 1
Instance Block 2
Constructor
请注意,我们有一个在两个实例{}
之后调用的static {}
{}
。 发生这种情况是因为我们在中间引入构造函数,在第一次调用构造函数时插入执行顺序。
当我正在处理这个答案时发现了这个问题 - https://stackoverflow.com/a/30837385/744133。
基本上我们观察到这会发生:
在第一次初始化对象时,根据发生的顺序混合静态和实例初始化的当前对象
对于所有下一次初始化,只能按发生顺序进行实例初始化,因为已经发生了静态初始化。
我需要研究继承的组合,以及对super和this的显式和隐式调用都会对此产生影响,并会随调查结果进行更新。 它可能类似于其他提供的答案,除了它们在静态初始化时出错。
链接地址: http://www.djcxy.com/p/20593.html上一篇: Are fields initialized before constructor code is run in Java?