我发现下面的代码发生了我的下巴:
public class MCVE {
{ // instance initializer
System.out.println(test); // cannot reference a field before it is defined
System.out.println(this.test);
}
private final String test = "wat";
}
第System.out.println(test);
行给出了错误
在定义之前无法引用字段。
但是System.out.println(this.test);
行不是
答案 0 :(得分:4)
与许多这些问题一样,这是因为the JLS says so.
8.3.2.3初始化期间使用字段的限制
成员声明只有在成员是类或接口C的实例(分别为
static
)字段并且满足以下所有条件时才需要以文本方式显示:
- 用法发生在C的实例(分别为
static
)变量初始值设定项或C的实例(分别为static
)初始值设定项中。- 用法不在作业的左侧。
- 使用方法是一个简单的名称。
- C是封闭用法的最里面的类或接口。
如果不满足上述四项要求中的任何一项,则为编译时错误。
在您的(失败)示例中,"简单名称"案件是不符合的条件。限定使用情况(使用this
)是解决编译时错误的漏洞。
在声明它们的行之前使用初始化块内的字段只能位于表达式的左侧(即赋值),除非它们是合格的(在您的情况下为
this.test
)
(更准确地解释为适应这个问题)
答案 1 :(得分:-3)
因为在创建lambda时可以捕获this
。捕获test
不是(它尚未定义)。稍后,在lambda内,您可以访问test
(通过this
)。