Java中静态变量继承的规则是什么? [英] What are the rules dictating the inheritance of static variables in 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屋!