2012-04-26 67 views
14

爲什麼我需要聲明local variablefinal如果在方法中定義的我的Inner class需要使用它?內部類和局部變量

實施例:

class MyOuter2 { 

private String x = "Outer2"; 

void doStuff() { 
    final String y = "Hello World"; 

    final class MyInner { 

     String z = y; 

     public void seeOuter() { 
      System.out.println("Outer x is "+x); 
      System.out.println("Local variable is "+y); 
      MyInner mi = new MyInner(); 
      mi.seeOuter(); 
     } 
    } 
} 

}

爲什麼字符串y需要是一個最終恆定?它如何影響?

+0

看看這個討論是否有助於http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/ – kosa 2012-04-26 17:52:59

+0

可能的重複[無法引用內部的非最終變量在不同的方法中定義的內部類](http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a- differen) – 2012-04-26 17:53:59

+0

[關於Java中局部最終變量的問題](http://stackoverflow.com/questions/5947352/question-about-local-final-variable-in-java)。 – Lion 2012-04-26 18:33:29

回答

13

答案是兩者在不同的範圍。所以這個變量在內部類訪問它之前可能會改變。使它最終防止這一點。

+2

這在java 8中已經改變了:http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html#accessing-members-of-an-enclosing-class – ohcibi 2014-03-20 20:38:00

3

我認爲這是爲了防止程序員會犯錯誤。這樣,編譯器會提醒程序員,當您離開該方法時,該變量將不再可用。這對循環很重要。想象一下這樣的代碼:

public void doStuff() 
{ 
    InnerClass cls[] = new InnerClass[100]; 
    for (int i = 0; i < 100; ++i) 
    { 
     cls[i] = new InnerClass() 
     { 
      void doIt() 
      { 
       System.out.println(i); 
      } 
     }; 
    } 
} 

doIt()方法被調用時,究竟會被打印?循環時更改了i。 爲了防止這種混淆,您必須將變量複製到局部變量或創建變量final,但是您將無法循環。

1

你的內部類是終局的,所以你不應該能夠從您的最終實體內任何修改。

15

局部變量總是生活在堆棧上,此刻的方法是在所有的局部變量都沒有了。

但是,即使在方法結束後,你的內部類對象可能在堆上(假設一個實例變量持有引用),所以在這種情況下,它不能訪問你的局部變量,除非你標記它們作爲最終

7

這是因爲在函數內部的內部類實際上使局部變量的副本,因爲局部變量可以在函數調用後銷燬,而本地類的實例仍然存在。爲了使局部變量的兩個副本始終具有相同的值(使它們看起來相同),必須將該變量聲明爲final。

0

根據Java的內存模型使用最後一個變量保證了最終的變量總是被初始化的。 當我們嘗試在沒有初始化的情況下使用本地變量時,會出現錯誤。 使用final來初始化已使用的局部變量的內部類。