-
new B:
- B 已分配,B 的大小(包括 A 的大小)所有字段默认
-
B() 的构造函数:
- super.A() 调用;递归:
-
A()的构造函数:
- super.Object() 调用;递归
- A 的所有初始化字段都被赋值:
A.this.y = 10;
- 其余的 A 构造函数语句被执行
- B 的所有初始化字段都被赋值:
B.this.x = 10; B.this.y = 20;
- 其余的 B 构造函数语句被执行
所以分配主要是在new中完成的。
在构造函数和字段初始化中完成的分配可以在下一个角转换中说明(要避免):
class A {
A() {
init(); // VERY BAD STYLE
}
protected void init() {
}
}
class B extends A {
String s1 = null;
String s2;
String s3 = "s3";
String s4;
String s5 = "s5";
B() {
// s1: null, s2: null, s3: null, s4: null, s5: null
// super() called, calling init()
// s1: "i1", s2: "i2", s3: "i3", s4: null, s5: null
// field initialisation:
// - s1 = null; s3 = "s3"; s5 = "s5";
// s1: null, s2: "i2", s3: "i3", s4: null, s5: "s5"
// remaining code of constructor
}
@Override
protected void init() {
// s1: null, s2: null, s3: null, s4: null, s5: null
s1 = "i1";
s2 = "i2";
s3 = "i3";
// s1: "i1", s2: "i2", s3: "i3", s4: null, s5: null
}
}
上面显示了字段的起始生命周期,以及如果有人在构造函数中使用可覆盖方法时的意外时刻。
它还表明在 A 的构造函数中已经存在超字段(默认值null, 0, false, 0.0, ...)。