2016-02-02 15 views
1

在下面的代码中,为什么Java认为简单名称numCows可能未被初始化?为什么使用限定符 - 这可以防止错误?Qualified在简单的名字在匿名类

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); 
} 

回答

2

Java Specification

对于一个空白......最终场x的每次访问,x必须访问之前明确赋值,或编译时错误.. 。当且仅当在赋值运算符的左边出现变量的简单名称(或者对于字段而言,其简单名称由此限定)时,才会定义此类赋值。出现在在类声明赋值运算符(=)的左手侧

final字段之前的类的构造final字段实例化。由this keywork限定的final字段在类构造函数之后实例化。请看下面的例子:

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_COWSthis限定符可确保在实例化MULTIPLY_COWS时明确分配了numCows

// This works fine, as well 
public final Function<Integer, Integer> DIVIDE_COWS = (k -> this.numCows * 2);