2012-02-05 52 views
0

我需要解釋爲什麼下面的代碼將無法編譯(在範圍和壽命方面):Java的範圍和使用壽命(內部類)

class ClassInMethod 
{ 
    public static void main(String[] args) 
    { 
     int local = 1; 

     class Inner 
     { 
     public void method() 
     { 
      System.out.println(local); 
     } 
     } 
    } 
} 

認爲這是因爲: 任何局部變量使用但未在內部類中聲明的內容必須聲明爲「最終」。因此,在本例中,'local'必須聲明爲final,因爲它的範圍和生命週期在主方法內結束(因此需要更改爲:final int local = 1;)。

任何其他建議?

+1

家庭作業?你有沒有試過編譯它? ;) – Jonathan 2012-02-05 21:07:36

+0

它是(因此標籤;);我有。但實際上,我認爲我想到了 - 如果你對我的第二次嘗試感興趣,請在〜30秒內查看我的帖子! – tommy1370 2012-02-05 21:14:24

+2

這個頁面可能有助於解釋_why_你需要變量是最終的:http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/ – DNA 2012-02-05 21:15:57

回答

1

你必須使局部變量final的原因是Java將它們的值複製到內部類的實例中。會發生什麼幕後是編譯器生成(大致)對應於這個字節碼:

class ClassInMethod { 
    public static void main(String[] args) { 
     int local = 1; 

     // this happens when you do: new Inner() 
     ClassInMethod_main_Inner inner = new ClassInMethod_main_Inner(); 
     inner.local = local; 
    } 
} 

// the inner class 
class ClassInMethod_main_Inner { 
    int local; 

    public void method() { 
     System.out.println(local); 
    } 
} 

如果localfinal,你可以改變它的時候Inner被實例化之間的值,當method()被稱爲,致電method()將使用舊值local。這可能是不正確的行爲。 final的原因是讓內部類的行爲更直觀。

(有沒有這個限制的語言,但它需要編譯器和運行時的明確支持。Java的開發人員到目前爲止還沒有決定獻出自己的努力來實現它。)

1

試着編譯它。編譯器輸出:

 
ClassInMethod.java:11: local variable local is accessed from within inner class; needs to be declared final 
    System.out.println(local); 
        ^
1 error 
+0

謝謝,我得到了那麼多我只是想確定我沒有錯過任何東西! – tommy1370 2012-02-05 21:17:56