问题描述
我有一堂课,超级
:
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中静态变量继承的规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!