2016-02-02 34 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);