Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果在类初始化期间调用重写的基方法,则不会初始化实例字段_Java - Fatal编程技术网

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

Java 如果在类初始化期间调用重写的基方法,则不会初始化实例字段,java,Java,有一个基类ServerAdapter: public class MyLinuxServerAdapter extends LinuxServerAdapter { public MyLinuxServerAdapter() { super(); } public static void main(String args[]) { ServerAdapter server = new MyLinuxServerAdapter();

有一个基类ServerAdapter:

public class MyLinuxServerAdapter extends LinuxServerAdapter {

    public MyLinuxServerAdapter() {
        super();
    }

    public static void main(String args[]) {
        ServerAdapter server = new MyLinuxServerAdapter();
    }
}
以及继承ServerAdapter的子类:

public class MyLinuxServerAdapter extends LinuxServerAdapter {

    public MyLinuxServerAdapter() {
        super();
    }

    public static void main(String args[]) {
        ServerAdapter server = new MyLinuxServerAdapter();
    }
}
继承LinuxServerAdapter的结束类:

public class MyLinuxServerAdapter extends LinuxServerAdapter {

    public MyLinuxServerAdapter() {
        super();
    }

    public static void main(String args[]) {
        ServerAdapter server = new MyLinuxServerAdapter();
    }
}
当我尝试在键上添加clickHandler时,会抛出NPE


为什么密钥没有初始化?这是初始化顺序以特定方式工作的情况吗?

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

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

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

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

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

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

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


这就是为什么有一条一般规则,即永远不要从构造函数调用虚方法。

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


这就是为什么有一条一般规则,您永远不应该从构造函数调用虚拟方法。

初始化顺序总是以特定的方式工作,JLS中详细介绍了这种方式。这就是为什么在构造过程中调用子类可能是粗略的一个原因。我猜initGUI是从基类调用的。你的类文本基本上是按调用顺序附加到基类末尾的。@JesanFafon你不必猜,它在第三行。哦,我明白了。首先,基类初始化发生,当我们调用在子类中实现的方法时,我们现在不调用该子类的c-tor。Hm.初始化顺序始终以特定方式工作,该方式在JLS中有详细说明。这就是为什么在构造过程中调用子类可能是粗略的一个原因。我猜initGUI是从基类调用的。你的类文本基本上是按调用顺序附加到基类末尾的。@JesanFafon你不必猜,它在第三行。哦,我明白了。首先,基类初始化发生,当我们调用在子类中实现的方法时,我们现在不调用该子类的c-tor。嗯。因此,避免这种情况的唯一方法是将所有字段初始化移动到initGUI实现中?这不是唯一的方法,而是更简单的方法。如果不是秘密,其他的变体是什么但无论如何,你的变体对我来说是好的。另一个可能的解决办法是使复选框保持静态。但是,这可能会产生其他问题,因为它将是所有实例之间的共享文件。另一个问题是将initGUI调用移动到实现了它的类LinuxServerAdapter。但我相信您希望从更高的级别执行调用,这是有意义的。因此,避免调用的唯一方法是将所有字段初始化移动到initGUI实现?这不是唯一的,但更简单。如果不是秘密,其他变体是什么但无论如何,你的变体对我来说是好的。另一个可能的解决办法是使复选框保持静态。但是,这可能会产生其他问题,因为它将是所有实例之间的共享文件。另一个问题是将initGUI调用移动到实现了它的类LinuxServerAdapter。但是我相信你想要从更高的层次上执行调用,这是有意义的。因此,为了避免违反规则,另一种方法是从子类c-tor调用virtual方法?因此,为了避免违反规则,另一种方法是从子类c-tor调用virtual方法?