Java不允许在供应商内部使用最终变量,因为它可能没有被初始化,而是先于“(this)”。变量使它编译并运行正常。
如果在分配变量之前调用此类供应商,则调用此类供应商会导致NullPointerException而不是编译器错误,并在调用之后按预期运行。
这种行为是在某处描述的吗?
我正在使用OpenJDK 1.8.0_151。
示例:
import java.util.function.Supplier;
class Example {
final String str;
Supplier<Integer> test1 = () -> str.length(); // DOES NOT COMPILE
Supplier<Integer> test2 = () -> this.str.length(); // DOES NOT COMPILE
Supplier<Integer> test3 = () -> (this.str).length(); // DOES NOT COMPILE
Supplier<Integer> test4 = () -> (this).str.length(); // OK
Example(String str) {
System.out.println(test4.get()); // NullPointerException
this.str = str;
System.out.println(test4.get()); // OK
}
}
---
javac Example.java
Example.java:7: error: variable str might not have been initialized
Supplier<Integer> test1 = () -> str.length(); // DOES NOT COMPILE
^
Example.java:8: error: variable str might not have been initialized
Supplier<Integer> test2 = () -> this.str.length(); // DOES NOT COMPILE
^
Example.java:9: error: variable str might not have been initialized
Supplier<Integer> test3 = () -> (this.str).length(); // DOES NOT COMPILE
^
3 errors
答案 0 :(得分:6)
每个局部变量(§14.4)和每个空白的最终字段(§4.12.4, §8.3.1.2)在访问时必须具有明确赋值 值发生。
对其值的访问包含变量的简单名称 (或者,对于字段,由此限定的字段的简单名称) 发生在表达式中的任何地方,除了作为左边的操作数 简单赋值运算符=(§15.26.1)。
str
是最终字段的简单名称,this.str
是由this
限定的字段的简单名称。 (this).str
不属于任何一种情况((this)
不算作“this
限定”,因此不会将其视为访问权限。