Java 在继承中,基构造函数调用虚方法,为什么类是Dervied并调用Dervied方法?

Java 在继承中,基构造函数调用虚方法,为什么类是Dervied并调用Dervied方法?,java,inheritance,constructor,Java,Inheritance,Constructor,我遇到了一个问题。以下代码未按预期运行: public class Dervied extends Base { private String name = "dervied"; public Dervied() { System.out.println(this.getClass().toString()); this.tellName(); } public void tellName() { System.ou

我遇到了一个问题。以下代码未按预期运行:

public class Dervied extends Base {
    private String name = "dervied";
    public Dervied() {
        System.out.println(this.getClass().toString());
        this.tellName();
    }
    public void tellName() {
        System.out.println("Dervied tell name: " + name);
    }
    public static void main(String[] args) {
        Base base = new Dervied();
    }
}

class Base {
    private String name = "base";
    public Base() {
        System.out.println(this.getClass().toString());
        this.tellName();
    }
    public void tellName() {
        System.out.println("Base tell name: " + name);
    }
}
结果是:

class Dervied
Dervied tell name: null
class Dervied
Dervied tell name: dervied 

但是为什么呢?环境是jdk1.8.0_60和Windows 10。当
new Dervied()
运行
Dervied()
方法时,调用基构造函数
base()
。但是为什么
Base()
中的打印类是
Dervied
?而
this.tellName()
Dervied
类中的方法作为多态性调用?

这就是为什么我们不应该从构造函数调用虚拟方法的原因。当构造函数运行时,有不同的阶段。首先运行基类构造函数,然后运行派生类构造函数

因此,虚拟调用将取决于构造函数所处的阶段,它可能会在尚未存在的对象上调用方法

这就是为什么会显示null,因为派生类中的“name”实例变量尚未初始化,因为基类构造函数正在运行,它调用派生类对象的tellName()

以下是约书亚·布洛赫(Joshua Bloch)的《有效的Java-第二版》中的相关引用:

超类构造函数在子类构造函数之前运行,因此 子类中的重写方法将在 子类构造函数已运行。如果重写方法依赖于任何 由子类构造函数执行初始化时,该方法将 表现不如预期


这就是为什么我们不应该从构造函数调用虚拟方法的原因。当构造函数运行时,有不同的阶段。首先运行基类构造函数,然后运行派生类构造函数

因此,虚拟调用将取决于构造函数所处的阶段,它可能会在尚未存在的对象上调用方法

这就是为什么会显示null,因为派生类中的“name”实例变量尚未初始化,因为基类构造函数正在运行,它调用派生类对象的tellName()

以下是约书亚·布洛赫(Joshua Bloch)的《有效的Java-第二版》中的相关引用:

超类构造函数在子类构造函数之前运行,因此 子类中的重写方法将在 子类构造函数已运行。如果重写方法依赖于任何 由子类构造函数执行初始化时,该方法将 表现不如预期


字段不具有多态性。字段不具有多态性。