Java 8供应商行为:可能未初始化最终变量

Java 8供应商行为:可能未初始化最终变量,java,compiler-errors,initialization,final,supplier,Java,Compiler Errors,Initialization,Final,Supplier,Java不允许在供应商内部使用final变量,因为它可能尚未初始化,但在变量前面加上“(this)。”可以使其编译并运行良好 此外,如果在分配变量之前调用,则调用此类供应商会导致NullPointerException而不是编译器错误,如果在分配变量之后调用,则会按预期运行 这种行为在什么地方被描述过吗 我正在使用OpenJDK1.8.0_151 例如: import java.util.function.Supplier; class Example { final String str;

Java不允许在供应商内部使用final变量,因为它可能尚未初始化,但在变量前面加上“(this)。”可以使其编译并运行良好

此外,如果在分配变量之前调用,则调用此类供应商会导致NullPointerException而不是编译器错误,如果在分配变量之后调用,则会按预期运行

这种行为在什么地方被描述过吗

我正在使用OpenJDK1.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
导入java.util.function.Supplier;
课例{
最终字符串str;
供应商test1=()->str.length();//未编译
供应商test2=()->this.str.length();//未编译
供应商test3=()->(this.str).length();//不编译
供应商测试4=()->(this).str.length();//确定
示例(字符串str){
System.out.println(test4.get());//NullPointerException
this.str=str;
System.out.println(test4.get());//确定
}
}
---
javac Example.java
java:7:error:variable str可能尚未初始化
供应商测试1=()->str.length();//不编译
^
java:8:error:variable str可能尚未初始化
供应商测试2=()->this.str.length();//不编译
^
java:9:error:variable str可能尚未初始化
供应商测试3=()->(this.str).length();//不编译
^
3个错误
来自:

每个局部变量(§14.4)和每个空白最终字段(§4.12.4), §8.3.1.2)在访问其 值出现

对其值的访问由变量的简单名称组成 (或者,对于字段,使用该字段限定的字段的简单名称) 在表达式中的任何位置出现,但作为表达式的左操作数除外 简单赋值运算符=(§15.26.1)


str
是最后一个字段的简单名称,
this.str
是由
this
限定的字段的简单名称
(this).str
不属于这两种情况(
(this)
不被视为“通过
this
”),因此它不被视为访问权限。

我在所有4个供应商身上都有一个编译错误。该行为将在此处某处记录:老实说,我认为lexer被绊倒了。任何其他场景都会在编译时正确地抓住这个问题,但是添加paren会让人忽略这一点。@YCF_L-从语义上讲,它的意思与此上下文中的
this
相同(与
3
(3)
的意思相同)。不过,这里似乎混淆了编译器的流分析。@Eran:是吗?那很有趣。你是如何编译的?(我没有发现
test4
on的编译错误,这说明它使用的是热点8u112。)是的。莱克瑟·邓在这件事上表现得很好。奇怪的是,帕伦斯会导致这种情况在这种狭隘的情况下发生。