静态最终字段的非法前向引用错误
问题内容:
我试图编译其中一个Java类javac
与拒绝 非法向前引用 错误,其中有问题的参考是词汇 后 的基准场。在显示相同行为时,将尽可能精简以下类:
java.util.concurrent.Callable
并且的许多用途Object
仅用作占位符,以删除不相关的代码段。
public class Test {
static final Object foo = method(new java.util.concurrent.Callable<Object>() {
@Override
public Object call() throws Exception {
return bar;
}
});
static final Object bar = foo;
static Object method(Object binder) {
return null;
}
}
使用编译时javac Test.java
,javac会显示以下错误消息:
Test.java:9: illegal forward reference
static final Object bar = foo;
^
因此,编译器抱怨bar
的声明引用,foo
而foo
应在bar
的声明范围内。但是,一旦删除了bar
in
foo
的声明的引用(例如,通过将第5行从更改return bar;
为)return null;
,编译器将接受该类。
如何解释呢?我对 前锋的 理解是错误 之后的词汇 意义 , 还是我不知道的某些特殊情况?
问题答案:
您对 前瞻性参考的 理解是正确的。第foo
9行上的引用根本不是 前向引用
,因为它在声明之前不会在文本上出现(请参阅Java语言规范
8.3.2.3节中对构成 前向引用
的定义)。
您观察到的行为是javac 错误
的症状。请参阅此错误报告。该问题似乎已在较新版本的编译器(例如OpenJDK
7)中得到解决。
它仅影响用作 最终* 字段初始化器的 前向引用 。该问题似乎同样影响静态和非静态字段。 *
请注意,对bar
in 的引用call()
是合法的 正向引用,
因为它发生在不同的类内部(请参见Java语言规范
8.3.2.3节中的示例)。
另外,请注意,以下每个更改都会使错误消失:
使bar
非决赛:
static Object bar = foo;
初始化bar
静态或实例初始化块:
static final Object bar;
static {
bar = foo;
}
将初始化foo
移至初始化程序块也有帮助。
bar
从非最终临时参考中初始化foo
:
static Object tmp = foo;
static final Object bar = tmp;
bar
用Test.foo
(由Tom Anderson找到)或this.foo
在非静态情况下初始化:
static final Object bar = Test.foo;
bar
使用foo
inside 移除并引用该对象call()
:
static final Object foo = method(new java.util.concurrent.Callable<Object>() {
@Override
public Object call() throws Exception {
return foo;
}
});