1. 程式人生 > >Java學習筆記23---內部類之局部內部類只能訪問final的局部變量

Java學習筆記23---內部類之局部內部類只能訪問final的局部變量

結束 stat nal person pos 內部類 style inter 周期

局部內部類是定義在方法體或代碼塊中的類,在筆記19中已有過簡單介紹。

今天要討論的是局部內部類為什麽只能訪問為常量的局部變量。

作者: 博客園--蟬蟬

請尊重作者勞動成果,轉載請在標題註明“轉載”字樣,並標明原文鏈接:

http://www.cnblogs.com/chanchan/p/8402411.html

參考資料:

http://www.cnblogs.com/dolphin0520/p/3811445.html

1.首先來了解一下局部內部類是如何訪問局部變量的

Person類是外部類,LoInClassIntf是接口,localInClassRe是Person類的成員方法,且返回值類型為LoInClassIntf;

方法內定義了一個局部內部類LoInnerClass,該內部類實現了接口LoInClassIntf;

方法內還定義了一個final的局部變量a,定義了一個LoInnerClass類型的對象引用loInC;

代碼如下:

 1     //筆記23:內部類--局部內部類--實現接口,返回內部類對象
 2     //接口
 3     public interface LoInClassIntf {
 4         void test();
 5     }
 6 
 7     //方法localInClassRe,返回值為LoInClassIntf,局部內部類來實現該接口,向上轉型
 8     public
LoInClassIntf localInClassRe() { 9 final int a = 1; //常量 10 11 //筆記23--內部類--局部內部類--實現接口 12 class LoInnerClass implements LoInClassIntf { 13 public void test() { 14 System.out.println("variable a:" + a); 15 } 16 } 17 18 LoInnerClass loInC = new
LoInnerClass(); 19 return loInC; 20 } 21 22 public static void main(String[] args) { 23 //筆記23--局部內部類 24 Person per = new Person(); 25 26 LoInClassIntf lInCIntf = per.localInClassRe(); 27 lInCIntf.test(); 28 }

輸出結果為:

1 variable a:1

成員方法localInClassRe執行中的內存示意圖如下:

技術分享圖片

成員方法localInClassRe執行後的內存示意圖如下:

技術分享圖片

分析:

成員方法localInClassRe執行後,方法體中的局部變量a和對象引用loInC都被釋放掉了,但分配在堆中的對象未回收,這時由main方法中的局部變量lInCIntf來指向它

到這裏還沒什麽問題,但第27行,lInCIntf調用了test方法,test方法中訪問到了成員方法localInClassRe中的局部變量a,而a此時已不存在了,所以就會出現錯誤;

即,局部變量與局部內部類的對象的生命周期不同;

為解決這一問題,Java把局部內部類要訪問的局部變量重新拷貝了一份,並把備份放在內部類的常量池中,這樣不論方法有沒有執行結束,拷貝都是存在的,就不會再出現訪問不存在的變量的錯誤了。

成員方法localInClassRe執行中的內存示意圖如下:

技術分享圖片

成員方法localInClassRe執行後的內存示意圖如下:

技術分享圖片

上面涉及到的局部變量a是方法體內定義的,如果局部內部類訪問的是方法體的參數呢?

Java采取的方法是,默認為局部內部類的構造方法傳入該參數作為構造方法的參數,然後用該參數來初始化內部類中拷貝的變量a。

局部內部類如何訪問局部變量的問題解決了,那麽為什麽只能訪問final的局部變量呢?

2.數據同步的問題

上面通過拷貝一份局部變量來解決生命周期不同的問題,如果方法體和局部內部類都改變了a的值會怎麽樣呢?

如下圖所示:

技術分享圖片

這樣兩個a不一致,就會出現數據不同步,下一步應該用a=2還是a=3呢?

為解決這個問題,Java規定局部內部類可訪問的局部變量必須為final的,即內部類不能改變要訪問的局部變量的值,這樣就不會出現數據不同步的問題了。

Java學習筆記23---內部類之局部內部類只能訪問final的局部變量