本文介绍了Java中静态变量继承的规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堂课,超级:

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

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

I also have another class, Sub that extends Super:

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

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

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

When I run it, it prints out bar.
My third (and last) class is 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 的内容会因您访问它的类而异.谁能解释一下?

I don't understand why the contents of foo vary depending on what class you're accessing it from. Can anyone explain?

推荐答案

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

Basically it's a matter of type initialization. The value of foo is set to "bar" when Sub is initialized. However, in your Testing class, the reference to Sub.foo is actually compiled into a reference to Super.foo, so it doesn't end up initializing Sub, so foo never becomes "bar".

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

If you change your Testing code to:

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 的值.这根本不是从哪里访问它的问题.

Then it would print out "bar" four times, because the first statement would force Sub to be initialized, which would change the value of foo. It's not a matter of where it's accessed from at all.

请注意,这不仅仅是关于类加载 - 而是关于类初始化.类可以在未初始化的情况下加载.例如:

Note that this isn't just about class loading - it's about class initialization. Classes can be loaded without being initialized. For example:

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 没有被初始化 - 但它肯定是 loaded,如果你删除 程序将会失败例如,在运行之前的 Sub.class 文件.

That still prints "foo" twice, showing that Sub isn't initialized - but it's definitely loaded, and the program will fail if you delete the Sub.class file before running it, for example.

这篇关于Java中静态变量继承的规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 21:26
查看更多