首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Java中通过方法定义静态字段之前,为什么可以访问它?

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

Stack Overflow用户
提问于 2013-01-30 00:48:37
回答 3查看 1K关注 0票数 16

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

代码语言:javascript
复制
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。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-30 00:54:01

这是在JLS 8.3.2.3中定义的。特别是:

成员的声明在使用之前需要以文本形式出现...如果使用发生在...C语言的静态初始化器。

当您调用cheat()时,您就绕过了这条规则。这实际上是该部分the list of the examples中的第五个示例。

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

票数 11
EN

Stack Overflow用户

发布于 2013-01-30 00:55:56

因为类加载的顺序是这样的:

  • 加载类定义(方法,为静态变量引用加载内存(对于test) -不初始化,但
  • 执行static初始化器(对于变量)和static块-按照

定义它们的顺序

因此,当您到达static块时,您已经准备好了方法定义,但是还没有准备好变量。使用cheat()时,您实际上读取的是一个未初始化的值。

票数 3
EN

Stack Overflow用户

发布于 2013-01-30 01:14:24

这是类加载发生的通用步骤。

-将类加载到内存中

  1. 验证-检查类e的二进制表示是否为correct
  2. Preparation -为类创建静态字段并将这些字段初始化为其标准默认values.
  3. Initializing -将调用静态字段的静态初始化器和初始化器

准备好之后,在你将静态变量赋值为true之前,你的测试将是false.Then,你的静态代码块将会是execute.That,这就是为什么你会得到false。

在这种情况下,尝试将静态变量设为最终值,这是因为编译器本身会将值嵌入字节码中(因为字段是final.In ),作为优化的一部分

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14587910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档