繁体   English   中英

为什么在超类的构造函数之后初始化成员对象?

[英]Why are member objects initialized after the super class's constructor?

昨天我遇到了一个有趣的问题,尽管解决方法非常简单,但是我对它的“原因”还是有点模糊。

我有一个具有私有成员变量的类,该类在实例化时分配,但是如果在超类的构造函数调用的抽象函数中使用它,则该变量没有值。 解决问题的方法非常简单,我只需要将变量声明为static并正确分配即可。 一些代码来说明问题:

class Foo extends BaseClass
{
    private final String bar = "fooBar!";
    public Foo()
    {
        super();
    }

    @Override 
    public void initialize()
    {
        System.out.println(bar);
    }
}

和基类:

abstract class BaseClass
{
    public BaseClass()
    {
        initialize();
    }

    public abstract void initialize();
}

在此示例中,当我们调用new Foo(); 它将输出(空)而不是预期的fooBar!

由于我们实例化了一个Foo类型的对象,是否应该在调用其(因此是其超类的)构造函数之前不对其成员进行分配和分配? 这是在Java语言中指定的地方还是JVM特定的?

感谢您的任何见解!

bar = "fooBar!";的分配bar = "fooBar!"; 在编译期间内联到构造函数中。

超类构造函数子类构造函数之前运行,因此,在语句之后执行是很自然的。

通常,从构造函数中调用可重写方法是不好的做法

它由Java语言规范定义。 在现实世界中,将其更改为静态几乎不会是可接受的解决方案。

请参见JLS 4.12.5变量的初始值JLS 8.3.2字段的初始化

总的来说,从构造函数中调用非最终方法是一种不好的做法。 原因是它可以(如果方法是抽象的,则肯定可以)在尚未初始化的类中调用方法:执行new Foo() ,在Foo构造函数之前调用BaseClass构造函数(构造函数),因此Foo.initialize本质上是在尚未完全构建的对象上工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM