为什么默认值会覆盖通过覆盖方法设置的值

时间:2019-05-24 15:23:49

标签: java

通过重写方法设置一个具有默认值的变量(例如本示例中的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;
        }
    }
}

我想知道是什么原因导致这种现象,除了没有默认值之外,是否有其他办法可以防止它发生?

1 个答案:

答案 0 :(得分:1)

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

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

在构造过程中,构造函数将字段测试的Initializer的值设置为false,该构造器在构造函数中处理其他逻辑之前,但是在调用基类构造函数之后进行处理。

在代码的执行顺序下查找:

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
        }
    }
}