我的节目
class Building {
Building() {
System.out.print("b ");
}
Building(String name) {
this();
System.out.print("bn " + name);
}
};
public class House extends Building {
House() {
System.out.print("h "); // this is line# 1
}
House(String name) {
this(); // This is line#2
System.out.print("hn " + name);
}
public static void main(String[] args) {
new House("x ");
}
}
我们知道编译器会将对super()
的调用写为子类构造函数的第一行。因此输出不应该是:
b
(在第2行
b
(再次来自编译器对super()的调用,在第1行之前)
h hn x
但输出是
b h hn x
为什么?
答案 0 :(得分:5)
当构造函数以对另一个构造函数(this
或super
)的调用开始时,编译器不会插入对超类的默认构造函数的调用。因此,调用树是:
main
\-> House(String) (explicit call)
|-> House() (explicit call)
| |-> Building() (implicit call)
| | |-> Object() (implicit call)
| | \-> print "b "
| \-> print "h "
\-> print "hn x"
答案 1 :(得分:3)
如果构造函数体不以显式构造函数开头 调用和声明的构造函数不是 原始类Object,然后构造函数体隐式开始 使用超类构造函数调用“super();”
答案 2 :(得分:1)
您的House(string name)
构造函数调用House()
,后者又调用Building()
。永远不会调用Building(string name)
。
如果您想明确致电Building(string name)
,可以在House(string name)
构造函数中添加:super(name);
而不是this();
答案 3 :(得分:1)
以下是代码的视觉控制流程:
new House("x ")---> House(args)---> House() --->Building()--->Object()
^^this() ^implicit ^implicit super() call
super()
call
<强> ---&GT;代表调用
输出 b(from building no-args), h(from no-args House), hn x (from args House)
b h h x x
据我所知,对super的隐式调用应该在this()之前, 对?第2行,在我的代码中
修改强>
构造函数中的第一行是使用super()调用超类构造函数或使用this()调用重载构造函数。如果使用this()调用重载的构造函数,则不会调用super()。
答案 4 :(得分:0)
House(x) -> House() + "hn" + "x"
Building() + "h" + "hn" +"x"
"b" + "h" + "hn" + "x"
对超类的调用只会被调用一次。
如果您想要调用Building(string name)
,则必须明确调用它。
我认为您可以更轻松地使用super()
代替this()