为什么您可以在通过Java中的方法定义静态字段之前访问静态字段?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (49)

我遇到了一件有趣的事情:

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都会告诉你这是错误的。在第二种情况下,作弊行为是确定的,但实际上它默认该字段testfalse。使用Sun JDK 6。

提问于
用户回答回答于

这在JLS 8.3.2.3中定义。尤其是:

如果用法在C的静态初始化器中出现,则成员的声明需要在文本使用之前出现[...]

当你给你打电话时,cheat()你要遵循这条规则。这实际上是该部分示例列表中的第五个示例。

请注意,cheat()将在静态初始化块中返回false,因为test尚未初始化。

用户回答回答于

因为类加载按此顺序工作:

  • 加载类定义(方法,签名)
  • 为静态变量引用分配内存(for test) - 尚未初始化
  • 执行static初始化程序(对于变量)和static块 - 以便它们被定义

所以,当你达到static阻塞时,你已经准备好了方法定义,但是没有准备好变量。随着cheat()你实际读取未初始化值。

扫码关注云+社区