在下面的代码中,为什么Java认为简单名称numCows
可能未初始化?为什么使用限定 - 这可以防止错误?
import java.util.function.Function;
public class CowFarm {
private final int numCows;
public CowFarm(int numCows) {
this.numCows = numCows;
}
// Fails to compile
//
// CowFarm.java:12: error: variable numCows might not have been initialized
public final Function<Integer, Integer> MULTIPLY_COWS = (k -> numCows * 2);
// Works fine
public final Function<Integer, Integer> DIVIDE_COWS = (k -> CowFarm.this.numCows * 2);
}
答案 0 :(得分:2)
出现在类声明中赋值运算符(=)左侧的对于...空白最终字段x的每次访问,x必须在访问之前明确赋值,否则发生编译时错误...如果发生此类分配,则定义为并且只有当变量的简单名称(或者,对于一个字段,其简单名称由此限定)出现在赋值运算符的左侧时。
final
字段在类构造函数中的final
字段之前被实例化。 final
键工作限定的this
字段在类构造函数之后实例化。请考虑以下示例:
public class Foo{
//Instantiated before constructor
final Bar bar1 = new Bar();
//Instantiated by constructor
final Bar bar2;
//Instantiated after constructor
final Bar bar3 = this.bar2;
//Compile time error
final Bar bar3 = bar2;
public Foo(Bar bar) {
this.bar2 = bar;
}
}
在您的情况下,当您尝试实例化numCows
时,问题是MULTIPLY_COWS
未明确分配。 this
限定符可确保在numCows
实例化时明确分配MULTIPLY_COWS
。
// This works fine, as well
public final Function<Integer, Integer> DIVIDE_COWS = (k -> this.numCows * 2);