一尘不染

有哪些规则指示Java中静态变量的继承?

java

我有一个类Super

public class Super {
    public static String foo = "foo";
}

我也有另一个类,Sub扩展了Super

public class Sub extends Super {
    static {
        foo = "bar";
    }

    public static void main (String[] args) {
        System.out.println(Super.foo);
    }
}

当我运行它时,它会打印出来bar
我的第三(也是最后一个)课是Testing

public class Testing {
    public static void main (String[] args) {
        System.out.println(Super.foo);
        System.out.println(Sub.foo);
        System.out.println(Super.foo);
    }
}

打印:

foo
foo
foo

我不明白为什么不同的内容foo取决于您从哪个类访问它。谁能解释?


阅读 242

收藏
2020-09-08

共1个答案

一尘不染

我不明白为什么foo的内容会根据您从哪个类访问它而变化。

基本上,这是类型初始化的问题。的值foo设置为"bar"when
Sub初始化。但是,在您的Testing类中,对的引用Sub.foo实际上已编译为对的引用Super.foo,因此它不会最终初始化Sub,因此foo永远不会成为"bar"

如果您将测试代码更改为:

public class Testing {
    public static void main (String[] args) {
        Sub.main(args);
        System.out.println(Super.foo);
        System.out.println(Sub.foo);
        System.out.println(Super.foo);
    }
}

然后它将打印出“ bar”四次,因为第一条语句将被强制Sub初始化,这将更改的值foo。根本不关从哪里访问它。

请注意,这不仅与类 加载 有关,还与类 初始化有关 。无需初始化即可加载类。例如:

public class Testing {
    public static void main (String[] args) {
        System.out.println(Super.foo);
        System.out.println(Sub.class);
        System.out.println(Super.foo);
    }
}

仍然会打印两次“ foo”,表明Sub尚未初始化-但肯定已 加载 ,例如,如果您Sub.class在运行文件之前删除文件,则该程序将失败。

2020-09-08