[英]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特定的?
感谢您的任何见解!
它由Java语言规范定义。 在现实世界中,将其更改为静态几乎不会是可接受的解决方案。
请参见JLS 4.12.5变量的初始值和JLS 8.3.2字段的初始化
总的来说,从构造函数中调用非最终方法是一种不好的做法。 原因是它可以(如果方法是抽象的,则肯定可以)在尚未初始化的类中调用方法:执行new Foo()
,在Foo
构造函数之前调用BaseClass
构造函数(构造函数),因此Foo.initialize
本质上是在尚未完全构建的对象上工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.