为什么在实例字段初始化方面 Java lambda 与嵌套 类 的处理方式不同?
Why are Java lambdas treated differently from nested classes with respect to instance field initialization?
使用 javac 1.8.0_77 这个 class 不编译:
import java.util.function.*;
public class xx {
final Object obj;
final Supplier<Object> supplier1 = new Supplier<Object>() {
@Override
public Object get() {
return xx.this.obj;
}
};
final Supplier<Object> supplier2 = () -> { return this.obj; };
xx(Object obj) {
this.obj = obj;
}
}
这是错误:
xx.java:12: error: variable obj might not have been initialized
final Supplier<Object> supplier2 = () -> { return this.obj; };
^
1 error
问题:
- 根据 JLS,此错误的生成是否正确?
- 如果是这样,JLS 处理
@FunctionalInterface
兰巴实现 (supplier2
) 与其等效的内部 class 实现 (supplier1
) 不同的原因是什么这方面?
浏览 JSR 335 的 JLS 更改,这对我来说似乎是一个遗漏:
- 对空白最终字段的访问受 JLS Chapter 16
管制
- 有一个部分 "Definite Assignment and Anonymous Classes" 在
supplier1
的情况下要求错误。
- JSR 335 spec 在第 16 章中只有一个边际变化,在本章中从未提及 "lambda" 或 "method references"。
事实上,第 16 章唯一的变化是(使用粗体字进行添加):
Throughout the rest of this chapter, we will, unless explicitly stated otherwise, write V to represent an in-scope (6.3) local variable or a blank final field (for rules of definite assignment) or a blank final variable (for rules of definite unassignment).
最重要的是,编译器在 lambda 情况下不抱怨似乎是正确的,但为了保持一致性,JLS 也应该修改以涵盖这种情况。
编辑::OpenJDK 已经有一个 spec bug,我们正在提议更改。
使用 javac 1.8.0_77 这个 class 不编译:
import java.util.function.*;
public class xx {
final Object obj;
final Supplier<Object> supplier1 = new Supplier<Object>() {
@Override
public Object get() {
return xx.this.obj;
}
};
final Supplier<Object> supplier2 = () -> { return this.obj; };
xx(Object obj) {
this.obj = obj;
}
}
这是错误:
xx.java:12: error: variable obj might not have been initialized
final Supplier<Object> supplier2 = () -> { return this.obj; };
^
1 error
问题:
- 根据 JLS,此错误的生成是否正确?
- 如果是这样,JLS 处理
@FunctionalInterface
兰巴实现 (supplier2
) 与其等效的内部 class 实现 (supplier1
) 不同的原因是什么这方面?
浏览 JSR 335 的 JLS 更改,这对我来说似乎是一个遗漏:
- 对空白最终字段的访问受 JLS Chapter 16 管制
- 有一个部分 "Definite Assignment and Anonymous Classes" 在
supplier1
的情况下要求错误。 - JSR 335 spec 在第 16 章中只有一个边际变化,在本章中从未提及 "lambda" 或 "method references"。
事实上,第 16 章唯一的变化是(使用粗体字进行添加):
Throughout the rest of this chapter, we will, unless explicitly stated otherwise, write V to represent an in-scope (6.3) local variable or a blank final field
(for rules of definite assignment) or a blank final variable (for rules of definite unassignment).
最重要的是,编译器在 lambda 情况下不抱怨似乎是正确的,但为了保持一致性,JLS 也应该修改以涵盖这种情况。
编辑::OpenJDK 已经有一个 spec bug,我们正在提议更改。