4 回答
TA贡献1883条经验 获得超3个赞
§15.11。字段访问表达式:
如果该字段是静态的:
对 Primary 表达式进行求值,并丢弃结果。如果主表达式的求值突然完成,则字段访问表达式也会出于同样的原因突然完成。
之前它指出字段访问由 标识 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类访问时看到 。FooxFoo.x
注意: 方法调用也被视为§15.8 主表达式Primary
中所示。
TA贡献1836条经验 获得超3个赞
第 16 章 明确分配
当发生对其值的任何访问时,每个局部变量(第 14.4 节)和每个空白最终字段(第 4.12.4 节、第 8.3.1.2 节)必须具有明确指定的值。
您尝试通过局部变量访问什么并不重要。规则是必须在此之前明确赋值。
要计算字段访问表达式 foo.x
,必须首先计算primary
它的部分 ( )。foo
这意味着将发生访问foo
,这将导致编译时错误。
对于局部变量或空白最终字段 x 的每次访问,必须在访问之前明确分配 x,否则会发生编译时错误。
TA贡献1785条经验 获得超8个赞
保持规则尽可能简单是有价值的,“不要使用可能尚未初始化的变量”就这么简单。
更重要的是,有一种调用静态方法的既定方法 - 始终使用类名,而不是变量。
System.out.println(Foo.x);
变量“foo”是不需要的开销,应该被删除,编译器错误和警告可以被视为有助于实现这一点。
TA贡献1796条经验 获得超4个赞
其他答案完美地解释了正在发生的事情背后的机制。也许您还想了解 Java 规范背后的基本原理。作为一个 Java 专家,我无法告诉你最初的原因,但让我指出这一点:
每一段代码要么有意义,要么触发编译错误。
(对于静态,因为实例是不必要的,
Foo.x
所以很自然。)现在,我们该怎么办
foo.x
(通过实例变量访问)?这可能是一个编译错误,如 C# 中的错误,或者
它有一个意义。因为
Foo.x
已经意味着“简单地访问”,所以该表达具有不同的含义x
是合理的;也就是说,表达式的每个部分都是有效且可访问的。foo.x
x
希望有知情人士能说出真正的原因。:-)
添加回答
举报