在匿名类

时间:2016-02-02 03:49:49

标签: java generics scope

在下面的代码中,为什么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);
}

1 个答案:

答案 0 :(得分:2)

来自Java Specification

  

对于...空白最终字段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);