super() 构造函数中的初始化问题
Initialization issues in super() constructor
有一个 Class 内部有 class。我预计输出将是 6 9
但突然它给了我0 9
。我想知道为什么我会得到如此意想不到的结果?
似乎在 A
class 中 f1
变量不知何故变成了零。
为什么会这样?
public static void main(String[] args) {
new B(6);
}
public static class A {
private int f1 = 7;
public A(int f2) {
this.f1 = f2;
initialize();
}
protected void initialize() {
System.out.println(f1);
}
}
public static class B extends A {
protected int f1 = 3;
public B(int f1) {
super(f1);
this.f1 += f1;
initialize();
}
protected void initialize() {
System.out.println(f1);
}
}
Class 字段分配在调用 super()
之后进行。这就是你得到 0.
的原因
调用 super(f1)
发生在 之前 赋值 protected int f1 = 3;
。 int
(原始类型)的默认值为 0
.
如您所知,函数 initialize()
在 B
中被覆盖,这是它执行的地方。
编辑:至于评论中的讨论,我从有效Java第2版第17条中找到了一些很好的参考:继承的设计和文档,否则禁止:
There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will be invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.
有一个 Class 内部有 class。我预计输出将是 6 9
但突然它给了我0 9
。我想知道为什么我会得到如此意想不到的结果?
似乎在 A
class 中 f1
变量不知何故变成了零。
为什么会这样?
public static void main(String[] args) {
new B(6);
}
public static class A {
private int f1 = 7;
public A(int f2) {
this.f1 = f2;
initialize();
}
protected void initialize() {
System.out.println(f1);
}
}
public static class B extends A {
protected int f1 = 3;
public B(int f1) {
super(f1);
this.f1 += f1;
initialize();
}
protected void initialize() {
System.out.println(f1);
}
}
Class 字段分配在调用 super()
之后进行。这就是你得到 0.
的原因
调用 super(f1)
发生在 之前 赋值 protected int f1 = 3;
。 int
(原始类型)的默认值为 0
.
如您所知,函数 initialize()
在 B
中被覆盖,这是它执行的地方。
编辑:至于评论中的讨论,我从有效Java第2版第17条中找到了一些很好的参考:继承的设计和文档,否则禁止:
There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will be invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.