我有一节课,Super:
public class Super {
public static String foo = "foo";
}
Run Code Online (Sandbox Code Playgroud)
我还有另一个类,Sub它扩展了Super:
public class Sub extends Super {
static {
foo = "bar";
}
public static void main (String[] args) {
System.out.println(Super.foo);
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它打印出来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);
}
}
Run Code Online (Sandbox Code Playgroud)
这打印:
foo
foo
foo
Run Code Online (Sandbox Code Playgroud)
我不明白为什么内容foo会有所不同,具体取决于您从哪个班级访问它.谁能解释一下?
Jon*_*eet 43
我不明白为什么foo的内容取决于你从哪个类访问它.
基本上这是类型初始化的问题.的值foo设置为"bar"当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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后它将打印出"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);
}
}
Run Code Online (Sandbox Code Playgroud)
那仍然会打印"foo"两次,显示它Sub没有被初始化 - 但是它肯定被加载了,例如,如果你Sub.class在运行之前删除文件,程序将会失败.