Java中的构造函数链,什么时候会调用super?

3
如果你有一个构造函数,在调用super()时调用this(),那么this()会在第一个被调用的构造函数中执行吗?还是在最后一个没有使用this()关键字的构造函数中执行?
主函数调用:new B()
public class A {
    public A(){
       System.out.print("A ");
    }
}
public class B extends A {
 public B(){
       // is super called here? Option 1
       this(1);
       System.out.print("B0 ");
    }
 public B(int i){
       // or is super called here? Option 2
       System.out.print("B1 ");
    }
}

在这个例子中,输出是"A B1 B0"。但对我而言不清楚super()构造函数是在选项1还是选项2中被调用(因为在这种情况下输出结果相同)。

2
B() 调用 B(int)(使用 this(1)),因此它不会调用 super。B(int) 没有显式的构造函数调用,因此编译器会生成对 super() 的调用。 - Mark Rotteveel
2个回答

2
您可以按照这个简单的规则推断出答案:
只有一个超类构造函数将被调用,而且它只会被调用一次。
因此,超类构造函数不可能从B()中调用,因为它将从B(int)中再次调用。
具体来说,在Java语言规范(JLS)第8.8.7节“构造函数体”中,我们读到:
如果构造函数体不以显式构造函数调用开头,并且正在声明的构造函数不是原始类Object的一部分,则构造函数体隐含地以超类构造函数调用“super();”开始,即其直接超类的不带参数的构造函数的调用。
换句话说,如果构造函数体确实以显式构造函数调用开头,则不会有隐式的超类构造函数调用。
(当JLS谈到构造函数体以“显式构造函数调用”开头时,它指的是同一类的另一个构造函数的调用。)

0

在实例化一个新对象时,使用new B(),它会自动调用无参构造函数。在您的情况下,是public B()

在无参构造函数中: 因为您的构造函数指定了要么调用另一个构造函数(使用this()),要么手动指定调用超类构造函数(使用super()),所以没有其他调用另一个构造函数。如果您的构造函数只有打印行(System.out.print("B0);),那么super()将被自动调用。现在,您正在调用this(1),因此您的第一个构造函数不会立即输出任何内容,但将进入您的第二个构造函数,其中包含一个int参数。

在第二个构造函数(带有int参数)中: 正如我已经指定的,如果你的构造函数没有显式调用this()super(),它会自动调用super()除非手动指定参数)。因为super()必须始终是构造函数中的第一个调用,所以它会在你的print之前执行,这意味着A()被调用。首先要打印的是A。接下来,将打印B1

回到你的第一个构造函数(无参数): this(1)已经被调用过了,所以它会移到下一条语句,即打印某些内容的语句。所以将打印B0

现在,作为一个总结,对于一个正确的答案:super()只会在public B(int i)中自动调用,因为你已经在第一个构造函数中指定了对this()的调用,并且只有当你不指定this()或显式调用super()时,super()才会被自动调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接