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

时间:2018-03-05 20:06:46

标签: java compiler-errors initialization final supplier

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

1 个答案:

答案 0 :(得分:6)

来自JLS version 9, chapter 16

  

每个局部变量(§14.4)和每个空白的最终字段(§4.12.4,   §8.3.1.2)在访问时必须具有明确赋值   值发生。

     

对其值的访问包含变量的简单名称   (或者,对于字段,由此限定的字段的简单名称)   发生在表达式中的任何地方,除了作为左边的操作数   简单赋值运算符=(§15.26.1)。

str是最终字段的简单名称,this.str是由this限定的字段的简单名称。 (this).str不属于任何一种情况((this)不算作“this限定”,因此不会将其视为访问权限。