有一个基类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
未初始化?这是初始化顺序以特定方式工作的情况吗?
答案 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
。
这就是为什么你应该永远不要从构造函数中调用虚方法的原因。