Java 创建子类时超类打印意外值
请您帮助理解以下java代码的输出,其中为Java 创建子类时超类打印意外值,java,constructor,Java,Constructor,请您帮助理解以下java代码的输出,其中为子类创建对象时调用超类的这个(0) 在本代码中,虽然代码中没有明确提到打印20,但为什么第一个值打印为20 class Superclass { Superclass() { this(0); System.out.println("1"); } Superclass(int x) { System.out.println("2" + x); } } class Subc
子类
创建对象时调用超类
的这个(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
”
实际上有,看看你的超类
Superclass() {
this(0);
System.out.println("1");
}
Superclass(int x) {
System.out.println("2" + x);
}
添加字符串
s被解释为串联,而不是普通的(值)添加。因此调用超类的默认构造函数
会触发这个(0)
,从而产生
System.out.println("2" + x);
=> System.out.println("2" + 0);
=> System.out.println("20");
20
1
41020
因此,打印20
整数加法 如果要将值添加为整数,则需要使用
int
值和not字符串
值,例如
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);
}
Superclass() {
this(0);
System.out.println("1");
}
Superclass(int x) {
System.out.println("2" + x);
}
现在在Java中,当创建子类时,总是需要调用超类的一个构造函数(根据语言的定义)
如果您没有明确指定这样的调用,那么它会尝试调用您的超类的默认构造函数。如果没有,它将不会编译。然而,您有这样一个默认构造函数,因此代码将等效于
Subclass(int x, int y) {
// Implicit call of default super-constructor
super();
System.out.println("4" + x + y);
}
所以你调用下面的构造函数
Subclass(int x, int y) {
System.out.println("4" + x + y);
}
Superclass() {
this(0);
System.out.println("1");
}
Superclass(int x) {
System.out.println("2" + x);
}
如上所示,它触发另一个构造函数
Subclass(int x, int y) {
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);
产生
System.out.println("2" + x);
=> System.out.println("2" + 0);
=> System.out.println("20");
20
1
41020
串加法
在本代码中,虽然代码中没有明确提及打印“20
”
实际上有,看看你的超类
Superclass() {
this(0);
System.out.println("1");
}
Superclass(int x) {
System.out.println("2" + x);
}
添加字符串
s被解释为串联,而不是普通的(值)添加。因此调用超类的默认构造函数
会触发这个(0)
,从而产生
System.out.println("2" + x);
=> System.out.println("2" + 0);
=> System.out.println("20");
20
1
41020
因此,打印20
整数加法 如果要将值添加为整数,则需要使用
int
值和not字符串
值,例如
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);
}
Superclass() {
this(0);
System.out.println("1");
}
Superclass(int x) {
System.out.println("2" + x);
}
现在在Java中,当创建子类时,总是需要调用超类的一个构造函数(根据语言的定义)
如果您没有明确指定这样的调用,那么它会尝试调用您的超类的默认构造函数。如果没有,它将不会编译。然而,您有这样一个默认构造函数,因此代码将等效于
Subclass(int x, int y) {
// Implicit call of default super-constructor
super();
System.out.println("4" + x + y);
}
所以你调用下面的构造函数
Subclass(int x, int y) {
System.out.println("4" + x + y);
}
Superclass() {
this(0);
System.out.println("1");
}
Superclass(int x) {
System.out.println("2" + x);
}
如上所示,它触发另一个构造函数
Subclass(int x, int y) {
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);
产生
System.out.println("2" + x);
=> System.out.println("2" + 0);
=> System.out.println("20");
20
1
41020
无论何时调用构造函数,第一条语句都需要调用超类的任何构造函数。如果不显式调用它,编译器将为您添加对默认构造函数的调用(如中所述) 在您的例子中,超类的默认构造函数调用另一个构造函数,后者依次调用
System.out.println(“2”+x)代码>
此语句将打印附加到Integer.valueOf(x).toString()
的字符串“2”,在您的情况下会产生字符串“20”(因为x==0)。每当调用构造函数时,第一个语句需要调用超类的任何构造函数。如果不显式调用它,编译器将为您添加对默认构造函数的调用(如中所述)
在您的例子中,超类的默认构造函数调用另一个构造函数,后者依次调用System.out.println(“2”+x)代码>
此语句将打印附加到Integer.valueOf(x).toString()
的字符串“2”,在您的情况下生成字符串“20”(因为x==0)。“为什么第一个值打印为“20”
”->因为您调用了子类的(int,int)
构造函数。在这个构造函数中,有一个(隐式)调用超类
的无参数构造函数。在超类
的无参数构造函数中,调用超类
的(int)
-constructor,然后打印一个“2”
,后跟x
的值,即0
,生成输出“20”
。试着用调试器一步一步地检查代码。我没有得到否决票。OP提供了我们需要的一切并解释了问题。也许是因为缺乏研究,但如果你不知道是为了什么,就很难进行研究。除了继承和对象创建,还有字符串+运算符的问题。。。所以不完全是重复的IMO“为什么第一个值被打印为”20“
”->,因为您调用了子类的(int,int)
构造函数。在这个构造函数中,有一个(隐式)调用超类
的无参数构造函数。在超类
的无参数构造函数中,调用超类
的(int)
-constructor,然后打印一个“2”
,后跟x
的值,即0
,生成输出“20”
。试着用调试器一步一步地检查代码。我没有得到否决票。OP提供了我们需要的一切并解释了问题。也许是因为缺乏研究,但如果你不知道研究的目的是什么,那就很难进行研究