首页 > 解决方案 > 为什么默认值会覆盖已通过覆盖方法设置的值

问题描述

设置一个具有默认值的变量,就像public boolean test = false;示例中一样,通过重写的方法导致它在到达构造函数后被设置为默认值。但是,如果我将其更改为public boolean test;它可以按预期工作。

public static void main(String[] args) {
    /* False */
    System.out.println(new Test2().test);
}

public static class Test {

    public Test() {
        this.test();

        /* True */
        System.out.println(((Test2) this).test);
    }

    public void test() {}

    public static class Test2 extends Test {

        public boolean test = false;

        public Test2() {
            /* False */
            System.out.println(this.test);
        }

        @Override
        public void test() {
            this.test = true;
        }
    }
}

我想知道是什么原因导致了这种行为,除了没有默认值之外,您是否可以采取任何措施来防止这种行为?

标签: java

解决方案


在 Java 中,没有参数的基类构造函数在派生类构造函数中自动调用。

在您的情况下,当您创建 Test2 类的实例时,Java 首先调用基类的构造函数(Test 的无参数构造函数),该构造函数从派生类调用覆盖 test() 方法。

字段 test 的初始值设定项在构造期间处理,就在构造函数中的任何其他逻辑之前,但在调用基类构造函数之后。

在下面找到代码的执行顺序:

public static void main(String[] args) {
    System.out.println(new Test2().test); // 6 - print false
}

public static class Test {

    public Test() {
        this.test(); // 1 - call the test method from derivative class

        System.out.println(((Test2) this).test); // 3 - print true
    }

    public void test() {}

    public static class Test2 extends Test {

        public boolean test = false; // 4 - set the test field to false

        public Test2() {
            System.out.println(this.test); // 5 - print false
        }

        @Override
        public void test() {
            this.test = true; // 2 - set the test field to true
        }
    }
}

推荐阅读