如果在类初始化期间调用重写的基本方法,则实例字段不会初始化

时间:2013-05-23 13:54:02

标签: java

有一个基类ServerAdapter

public abstract class ServerAdapter {
    public ServerAdapter() {
        initGUI();
    }

    protected abstract void initGUI();
}

继承ServerAdapter的子类:

public abstract class LinuxServerAdapter extends ServerAdapter {
    protected CheckBox key = new CheckBox();

    public LinuxServerAdapter() {
        super();
    }

    @Override
    public void initGUI() {
        //NPE is thrown here, because key = null
        key.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                //Something happens here
            }
        });
    }
}

继承LinuxServerAdapter的结束类:

public class MyLinuxServerAdapter extends LinuxServerAdapter {

    public MyLinuxServerAdapter() {
        super();
    }

    public static void main(String args[]) {
        ServerAdapter server = new MyLinuxServerAdapter();
    }
}

当我尝试在键上添加clickHandler时,会抛出NPE。

为什么key未初始化?这是初始化顺序以特定方式工作的情况吗?

2 个答案:

答案 0 :(得分:5)

只需在init方法中初始化。毕竟这就是目的..

@Override
public void initGUI() {
    key = new CheckBox();
    key.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
            //Something happens here
        }
    });

父母课程在孩子面前得到实例化。在您的顶级父类中,您调用initGUI()抽象方法,该方法的实现位于其子级中,该子级尚未初始化其他字段。将字段的实际初始化移动到initGUI()方法是有意义的,它符合名称约定和你得到的逻辑。

答案 1 :(得分:1)

实例变量声明中的赋值以及class块中非静态块中的任何语句在 super()调用返回后运行。如果从超类的构造函数中调用子类的方法,它将使用未初始化的this

这就是为什么你应该永远不要从构造函数中调用虚方法的原因。