【问题标题】:Superclass printing unexpected value when Subclass is created [duplicate]创建子类时超类打印意外值[重复]
【发布时间】:2018-05-23 13:22:27
【问题描述】:

您能否帮助理解以下 java 代码的输出,其中在为 Subclass 创建对象时调用 Superclassthis(0)

在这段代码中虽然没有提到显式打印20,为什么第一个值打印为20

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

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

class Subclass extends Superclass {
    Subclass(int x) {
        System.out.println("3" + x);
    }

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

public class practiceTest {
    public static void main(String[] args) {
        Subclass s = new Subclass(10, 20);
    }
}

【问题讨论】:

  • "为什么第一个值打印为"20"" -> 因为你调用了Subclass(int, int) 构造函数。在此构造函数中,您可以(隐式)调用Superclass 的无参数构造函数。在Superclass 的无参数构造函数中,调用Superclass(int)-构造函数,然后打印"2",然后是x 的值,即0,产生输出"20"。尝试使用调试器单步执行代码。
  • 我没有得到反对票。 OP提供了我们需要的一切并解释了问题。也许是因为缺乏研究,但如果你不知道是为了什么,就很难研究。
  • 除了继承和对象创建之外,还有字符串 + 运算符问题......所以......不完全是重复的 IMO

标签: java constructor


【解决方案1】:

字符串加法

在此代码中,虽然代码中没有提及显式打印“20

其实有,看看你的Superclass

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

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

加法被解释为串联,而不是普通加法(值的)。因此调用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

【讨论】:

  • 知道了。感谢您的详细解释,清楚的是它的水晶。
【解决方案2】:

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

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

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

【讨论】:

  • 知道了。非常感谢您的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-14
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多