2013-12-14 35 views
4

以下代碼定義方法中的類。在方法中定義的內部類需要方法中聲明的變量爲final,如果它們是從內部類中訪問的

final class OuterClass 
{ 
    private String outerString = "String in outer class."; 

    public void instantiate() 
    { 
     final String localString = "String in method."; // final is mandatory. 

     final class InnerClass 
     { 
      String innerString = localString; 

      public void show() 
      { 
       System.out.println("outerString : "+outerString); 
       System.out.println("localString : "+localString); 
       System.out.println("innerString : "+innerString); 
      } 
     } 

     InnerClass innerClass = new InnerClass(); 
     innerClass.show(); 
    } 
} 

調用方法instantiate()

new OuterClass().instantiate(); 

下面的語句,

final String localString = "String in method."; 

instantiate()方法內導致編譯時間錯誤如下,如果final改性劑被除去

局部變量localString從內部類中訪問;需要 被聲明爲final

爲什麼局部變量localString需要申報final,在這種情況下?

回答

4

它在this article定律描述得非常好:

..在一個匿名類中的方法真的沒有訪問本地 變量和方法的參數。相反,當實例化匿名類的對象時,局部變量局部變量 和對象方法所涉及的方法參數的副本作爲對象中的實例變量存儲在 中。匿名類的對象中的方法真正訪問這些隱藏的實例變量。 因此, 由 方法訪問的本地變量和方法參數必須聲明爲最終的本地類,以防止在對象實例化後它們的值從 變爲

有關詳細信息和進一步說明,請參閱JLS-8.1.3. Inner Classes and Enclosing Instances

3

這是通過以下方式實現的:將localString的值傳遞給構造中的內部類,並將其存儲在隱藏字段中。由於現在有兩個值的副本,所以如果在任何點更改了外部變量的值,將會非常令人困惑。內部副本仍然具有內部類構建時的舊值。

因此,Java要求它被聲明爲final,所以這是不可能的。

相關問題