我遇到了一件有趣的事情:
static {
System.out.println(test); // error cannot reference a field before it is defined
System.out.println(cheat()); // OK!
}
private static boolean cheat() {
return test;
}
private static boolean test = true;
public static void main(String args[]) {}
第一种方法是错误的,您的编译器和IDE都会告诉您它是错误的。在第二种情况下,作弊是可以的,但它实际上将字段test
默认为false
。使用Sun JDK 6。
发布于 2013-01-30 00:54:01
这是在JLS 8.3.2.3中定义的。特别是:
成员的声明在使用之前需要以文本形式出现...如果使用发生在...C语言的静态初始化器。
当您调用cheat()
时,您就绕过了这条规则。这实际上是该部分the list of the examples中的第五个示例。
请注意,由于test
尚未初始化,因此cheat()
将在静态初始化器块中返回false。
发布于 2013-01-30 00:55:56
因为类加载的顺序是这样的:
test
) -不初始化,但static
初始化器(对于变量)和static
块-按照定义它们的顺序
因此,当您到达static
块时,您已经准备好了方法定义,但是还没有准备好变量。使用cheat()
时,您实际上读取的是一个未初始化的值。
发布于 2013-01-30 01:14:24
这是类加载发生的通用步骤。
-将类加载到内存中
准备好之后,在你将静态变量赋值为true之前,你的测试将是false.Then,你的静态代码块将会是execute.That,这就是为什么你会得到false。
在这种情况下,尝试将静态变量设为最终值,这是因为编译器本身会将值嵌入字节码中(因为字段是final.In ),作为优化的一部分
https://stackoverflow.com/questions/14587910
复制相似问题