gpt4 book ai didi

java - 扩展类构造函数被调用两次

转载 作者:行者123 更新时间:2023-12-02 10:51:32 26 4
gpt4 key购买 nike

对于以下代码,结果为

I am in B, value is 0
I am in B, value is 44
22

public class Test {
public static void main(String[] args) {
P b = new B();
System.out.println(b.a);
}

static class P {
public int a = 11;

public P() {
a = 22;
diplay();
}

public void diplay() {
System.out.println("I am in P, value is " + a);
}
}

static class B extends P {
int a = 33;

public B() {
a = 44;
diplay();
}

public void diplay() {
System.out.println("I am in B, value is " + a);
}
}
}

首先,为什么构造函数会被调用两次?
为什么b.a 的值为22
最后,为什么第一个a的值为0

最佳答案

只要您不提供对父类(super class)构造函数的显式调用,Java 编译器就会为您插入对默认父类(super class)构造函数的隐式调用(无参数)。就好像您的 B 构造函数实际上是:

public B() {
super();
a = 44;
diplay();
}

对父类(super class)构造函数的调用会调用 P 构造函数,后者又调用 diplay。该对象实际上是一个 B,因此通过多态性,将调用 Bdiplay 方法。

此时,您已经泄漏了您的子类实例,因为它尚未完全构造。因此,B 的变量a,隐藏了P的变量a,还没有被初始化,所以它仍然有默认值,0.

然后,父类(super class) P 构造函数完成,B 构造函数的其余部分运行,同时也会调用 diplay。此调用会看到初始化的 44 值。

构造函数不会被调用两次;子类构造函数 B 隐式调用父类(super class)构造函数 P,并且两个构造函数都调用 diplay

回到main,您引用了字段a,但引用是在P类型的变量上。没有字段多态性,因此即使运行时对象是 B,也会检索到 Pa 值,即初始化为22

此代码说明了为什么通常不是一个好主意

  1. 在构造函数完成之前泄漏 this 对象实例,并且
  2. 有意在子类中声明与父类(super class)中同名的变量。

关于java - 扩展类构造函数被调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51073396/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com