gpt4 book ai didi

java - 为什么我们不能通过未初始化的局部变量访问静态内容?

转载 作者:行者123 更新时间:2023-12-02 07:07:00 25 4
gpt4 key购买 nike

看下面的代码:

class Foo{
public static int x = 1;
}

class Bar{
public static void main(String[] args) {
Foo foo;
System.out.println(foo.x); // Error: Variable 'foo' might not have been initialized
}
}

正如您在尝试通过未初始化局部变量Foo foo;代码foo.x<访问静态字段x时所看到的那样 生成编译错误:变量“foo”可能尚未初始化

这个错误可能看起来是有道理的,但只有当我们意识到要访问 static 成员时,JVM 实际上并没有这样做。 使用变量的,但仅使用其类型

例如,我可以使用值 null 初始化 foo,这样我们就可以毫无问题地访问 x:

Foo foo = null;
System.out.println(foo.x); //compiles and at runtime prints 1!!!

这种情况之所以有效,是因为编译器意识到 x 是静态的,并将 foo.x 视为像 Foo.x 那样编写(位于至少到目前为止我是这么想的)。

那么为什么编译器突然坚持要求 foo 具有一个它根本不会使用的值?

<小时/>

免责声明:这不是在实际应用程序中使用的代码,而是一个有趣的现象,我在 Stack Overflow 上找不到答案,所以我决定询问一下。

最佳答案

§15.11. Field Access Expressions :

If the field is static:

The Primary expression is evaluated, and the result is discarded. If evaluation of the Primary expression completes abruptly, the field access expression completes abruptly for the same reason.

之前它指出字段访问由 Primary.Identifier 标识.

这表明即使它似乎没有使用Primary ,它仍然被评估,然后结果被丢弃,这就是为什么它需要初始化。当评估按照引用中所述停止访问时,这可能会产生影响。

编辑:

这是一个简短的示例,只是为了直观地演示 Primary即使结果被丢弃也会被评估:

class Foo {
public static int x = 1;

public static Foo dummyFoo() throws InterruptedException {
Thread.sleep(5000);
return null;
}

public static void main(String[] args) throws InterruptedException {
System.out.println(dummyFoo().x);
System.out.println(Foo.x);
}
}

在这里你可以看到dummyFoo()仍在评估,因为 print延迟了 5 秒 Thread.sleep()即使它总是返回 null被丢弃的值。

如果未计算表达式,则 print会立即出现,在类Foo时可以看到直接用于访问xFoo.x .

注意:方法调用也被视为 Primary显示于 §15.8 Primary Expressions .

关于java - 为什么我们不能通过未初始化的局部变量访问静态内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57964026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com