你对前向参考的理解是正确的.对第9行的foo的引用根本不是前向引用,因为它在声明之前没有以文字形式显示(参见
The Java Language Specification第8.3.2.3节中什么构成前向引用的定义).
您观察到的行为是javac错误的症状.请参见this bug report.问题似乎在编译器的较新版本中已修复,例如. OpenJDK 7.
它仅影响用作最终字段的初始化器的前向引用.这个问题似乎同样影响静态和非静态字段.
请注意,call()中对bar的引用是合法的转发引用,因为它发生在不同的类中(参见The Java Language Specification第8.3.2.3节中的示例).
另外,请注意,以下每个更改都会使错误消失:
制作酒吧非最终:
static Object bar = foo;
在静态或实例初始化程序块中初始化栏:
static final Object bar;
static {
bar = foo;
}
将foo的初始化移动到初始化程序块也有帮助.
从非最终临时引用初始化栏到foo:
static Object tmp = foo;
static final Object bar = tmp;
使用Test.foo(由Tom Anderson发现)或非静态情况下的this.foo初始化栏:
static final Object bar = Test.foo;
使用foo内的call()方法来取消栏并引用对象:
static final Object foo = method(new java.util.concurrent.Callable() {
@Override
public Object call() throws Exception {
return foo;
}
});