关于在Java中使用继承时构造函数初始化序列

时间:2018-06-19 09:47:09

标签: java inheritance constructor

我正在尝试在“Java第4版中的Thingking”中进行“重用/ E07_SimpleInheritance2”练习。代码有效,但控制台中的输出是:

A: New instance C
B: New instance B
C: New instance C

但我认为C应该在B的前面,因为句子“System.out.println('C:'+ str);”在C2的构造函数中,然后是实例B.嗯,为什么不呢?

好的,我刚刚意识到初始化时,序列是:(静态变量,静态字段)> (变量,字段)>构造函数。这就是原因。问题解决了,谢谢你们这些家伙:)

class A2{
    A2(String str){
        System.out.println("A: " + str);
    }
}

class B2{
    B2(String str){
        System.out.println("B: " + str);
    }
}

class C2 extends A2{
    C2(String str){
        super(str);
        System.out.println("C: " + str); //I think it should work first
    }
    B2 b = new B2("New instance B"); //Then followed by B
}
public class Q7_7_SimpleInheritance2 {

    public static void main(String[] args) {
        C2 c = new C2("New instance C");

    }

}

3 个答案:

答案 0 :(得分:4)

当创建C2实例时,首先要执行的是A2(超类)构造函数,这会导致首先打印A: New instance C

然后在C2构造函数的主体之前初始化C2的实例变量。因此B2 b = new B2("New instance B");System.out.println("C: " + str);之前执行,因此B: New instance B是第二个输出行,C: New instance C是最后一行。

您可能对构造函数之后声明的实例变量b感到困惑,但这没有任何意义。

如下更改代码可能会减少混淆,但会产生完全相同的输出:

class C2 extends A2 
{
    B2 b = new B2("New instance B");
    C2(String str){
        super(str);
        System.out.println("C: " + str);
    }
}

答案 1 :(得分:2)

这里的关键点是,在实例化类时,会发生以下情况(按此顺序):

  1. super被称为
  2. 类成员已初始化
  3. 执行其他构造函数语句
  4. 23解释了B: New instance B之前打印C: New instance C的原因。

答案 2 :(得分:-1)

A在C之前,因为C的构造函数在写入sysout之前调用A的构造函数。