Java中静态变量继承的规则是什么? [英] What are the rules dictating the inheritance of static variables in Java?

查看:26
本文介绍了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?

推荐答案

我不明白为什么 foo 的内容会因您访问它的类而异.

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

基本上是类型初始化的问题.当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中静态变量继承的规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆