Java:初始化的内联私有final字段为null

时间:2015-11-18 15:31:56

标签: java inheritance abstract

我无法理解为什么私有变量为null,即使它是内联初始化的。这是我的代码片段:

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

    protected abstract void initializeLayout();
    protected void initialize() {
        // Do something
        initializeLayout();
    }
}

public abstract class B extends A {
    private final Object myVariable = new Object();

    @Override
    protected void initializeLayout() {
        // Do something with myVariable
    }
}

好吧,当此代码到达B.initailizeLayout时,myVariable为NULL。我认为内联字段在其他所有内容之前都已初始化,甚至在构造函数之前。我错了什么?

2 个答案:

答案 0 :(得分:19)

超类A的构造函数(调用initialize()调用B的{​​{1}})在初始化子类B的实例变量之前执行。因此,您的实例变量initializeLayout()在那时仍为空。

答案 1 :(得分:2)

子B的(可能是隐式的)构造函数将执行以下操作:

  • 将所有字段归零(null,0,0.0,false)
  • 调用super A的构造函数
    • 调用B.initializeLayout,所有字段为空
  • 初始化在其声明中分配的所有字段
  • 调用构造函数的其余部分

所以你在尝试做的事情在java中非常容易出错。 许多样式检查器将此代码标记为错误样式(在构造函数中调用非最终方法)。

你可以做

private /*final*/ Object myVariable; // Must not be initialized!

@Override
protected void initializeLayout() {
    myVariable = new Object();
    // Do something with myVariable
}

初始化myVariable会在调用initializeLayout后初始化myVariable。

最好避免。