输出说明

时间:2012-12-19 16:56:12

标签: java output

我的节目

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行

之前从编译器调用super()调用)

b(再次来自编译器对super()的调用,在第1行之前)

h hn x

但输出是

b h hn x

为什么?

5 个答案:

答案 0 :(得分:5)

当构造函数以对另一个构造函数(thissuper)的调用开始时,编译器不会插入对超类的默认构造函数的调用。因此,调用树是:

main
 \-> House(String)                (explicit call)
      |-> House()                 (explicit call)
      |    |-> Building()         (implicit call)
      |    |    |-> Object()      (implicit call)
      |    |    \-> print "b "
      |    \-> print "h "
      \-> print "hn x"

答案 1 :(得分:3)

根据JLS 8.8.7

  

如果构造函数体不以显式构造函数开头   调用和声明的构造函数不是   原始类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()