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

Java 8 supplier behaviour: final variable might not be initialized

Java 不允许在供应商内部使用 final 变量,因为它可能未被初始化,但在“(this)”之前。变量使它编译并且 运行 很好。

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

是否在某处描述了这种行为?

我正在使用 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

来自JLS version 9, chapter 16

Each local variable (§14.4) and every blank final field (§4.12.4, §8.3.1.2) must have a definitely assigned value when any access of its value occurs.

An access to its value consists of the simple name of the variable (or, for a field, the simple name of the field qualified by this) occurring anywhere in an expression except as the left-hand operand of the simple assignment operator = (§15.26.1).

str是final字段的简称,this.strthis限定的字段的简称。 (this).str 不属于这两种情况((this) 不算作 "qualified by this"),因此不算作访问。