创建子类时,超类打印意外值

时间:2017-12-09 13:07:20

标签: java constructor

在为this(0)创建对象时,您可以帮助理解下面的java代码的输出,其中Superclass的{​​{1}}被调用。

在此代码中虽然代码中没有提及明确打印Subclass,但为什么第一个值打印为20

20

2 个答案:

答案 0 :(得分:2)

字符串添加

  

在此代码中,虽然代码中没有提及明确打印" 20"

实际上有,看看你的Superclass

Superclass() {
    this(0);
    System.out.println("1");
}

Superclass(int x) {
    System.out.println("2" + x);
}

String s的加法被解释为连接,而不是普通加法(值)。因此,调用Superclass的默认构造函数会触发this(0),从而产生

    System.out.println("2" + x);
=>  System.out.println("2" + 0);
=>  System.out.println("20");

因此打印20

整数添加

如果您想将值添加为整数,则需要使用int值和 String值,例如

Superclass(int x) {
    System.out.println(2 + x);
}

然后你也会得到

    System.out.println(2 + x);
=>  System.out.println(2 + 0);
=>  System.out.println(2);

构造链

好的,那么如果你打电话

会发生什么
Subclass s = new Subclass(10, 20);

嗯,首先,当然,你会触发这个构造函数

Subclass(int x, int y) {
    System.out.println("4" + x + y);
}

现在在Java中,在创建子类时,总是需要调用超类的构造函数之一(根据语言的定义)。

如果您没有明确指定此类调用,那么它会尝试调用您的超类的默认构造函数。如果没有,它就不会编译。但是,您有这样的默认构造函数,因此代码将等同于

Subclass(int x, int y) {
    // Implicit call of default super-constructor
    super();
    System.out.println("4" + x + y);
}

所以你调用以下构造函数

Superclass() {
    this(0);
    System.out.println("1");
}

,如上所示,触发其他构造函数

Superclass(int x) {
    System.out.println("2" + x);
}

因此,如果解析此链,您将获得以下输出

// from Superclass(int x)
System.out.println("2" + 0);
// from Superclass()
System.out.println("1");
// from Subclass(int x, int y)
System.out.println("4" + 10 + 20);

产生

20
1
41020

答案 1 :(得分:0)

每当调用构造函数时,第一个语句都需要调用超类的任何构造函数。如果您没有显式调用它,编译器将为您添加对默认构造函数的调用(如this question中所述。)。

在你的情况下,你的超类的默认构造函数调用另一个构造函数,后者又调用System.out.println("2" + x);

此语句将打印附加到Integer.valueOf(x).toString()的字符串“2”,在您的情况下生成字符串“20”(因为x == 0)。