gpt4 book ai didi

java - 静态最终字段的非法前向引用错误

转载 作者:搜寻专家 更新时间:2023-10-30 21:05:27 57 4
gpt4 key购买 nike

我正在尝试编译一个 Java 类,它被 javac 拒绝并出现非法前向引用 错误,其中违规引用在词法上之后引用的字段。以下类在显示相同行为的同时被尽可能地精简:

java.util.concurrent.CallableObject 的许多用途只是用作占位符以删除不相关的代码片段。

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 的声明引用了 foofoo 应该在 bar 的范围内> 的声明。但是一旦 foo 声明中的 bar 引用被移除,例如通过将第 5 行从 return bar; 更改为 return null;,类被编译器接受。

这怎么解释?我对forward 的理解是lexically after 的理解是错误的还是这是我不知道的一些特殊情况?

最佳答案

您对前向引用的理解是正确的。第 9 行对 foo 的引用根本不是前向引用,因为它没有以文本形式出现在它的声明之前(请参阅什么构成 的定义) The Java Language Specification 的第 8.3.2.3 节中的前向引用

您观察到的行为是 javac 错误 的症状。参见 this bug report .该问题似乎已在较新版本的编译器中得到解决,例如OpenJDK 7 .

它只影响用作final 字段初始化器的前向引用。该问题似乎同样影响静态和非静态字段。

请注意,call() 中对 bar 的引用是合法的前向引用,因为它出现在不同的类中(参见示例The Java Language Specification 的第 8.3.2.3 节)。

另请注意,以下每个更改都会使错误消失:

使 bar 成为非最终的:

static Object bar = foo;

在静态或实例初始化 block 中初始化bar:

static final Object bar;

static {
bar = foo;
}

foo 的初始化移动到初始化程序 block 也有帮助。

从对 foo 的非最终临时引用初始化 bar:

static Object tmp = foo;
static final Object bar = tmp;

在非静态情况下,使用 Test.foo(由 Tom Anderson 找到)或使用 this.foo 初始化 bar:

static final Object bar = Test.foo;

删除 bar 并在 call() 中使用 foo 引用对象:

static final Object foo = method(new java.util.concurrent.Callable<Object>() {
@Override
public Object call() throws Exception {
return foo;
}
});

关于java - 静态最终字段的非法前向引用错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8234645/

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