內部類訪問局部變量的時候,為什么變量必須加上final修飾


這里的局部變量就是在類方法中的變量,能訪問方法中變量的類當然也是局部內部類了。
我們都知道,局部變量在所處的函數執行完之后就釋放了,但是內部類對象如果還有引用指向的話它是還存在的。例如下面的代碼:

class Outer{ public static void main(String[] args){ Outer out = new Outer(); Object obj = out.method(); } Object method(){ int locvar = 1; class Inner{ void displayLocvar(){ System.out.println("locvar = " + locvar); } } Object in = new Inner(); return in; } } 

當out.method()方法執行結束后,局部變量 locvar 就消失了,但是在method()方法中 obj in = new Inner() 產生的 in 對象還存在引用obj,這樣對象就訪問了一個不存在的變量,是不允許的。這種矛盾是由局部內部類可以訪問局部變量但是局部內部類對象和局部變量的生命周期不同而引起的。

局部內部類訪問局部變量的機制

在java中,類是封裝的,內部類也不例外。我們知道,非靜態內部類能夠訪問外部類成員是因為它持有外部類對象的引用 Outer.this, 就像子類對像能夠訪問父類成員是持有父類對象引用super一樣。局部內部類也和一般內部類一樣,只持有了Outer.this,能夠訪問外部類成員,但是它又是如何訪問到局部變量的呢?

實際上java是將局部變量作為參數傳給了局部內部類的構造函數,而將其作為內部類的成員屬性封裝在了類中。我們看到的內部類訪問局部變量實際上只是訪問了自己的成員屬性而已,這和類的封裝性是一致的。那么上面的代碼實際上是這樣:

Object method(){ int locvar = 1; class Inner{ private int obj; public Inner(int obj){ this.obj = obj; } void displayLocvar(){ System.out.println("locvar = " + locvar); } } Object in = new Inner(locvar); //將locvar作為參數傳給構造,以初始話成員 return in; } 

那么問題又來了,我們寫代碼的目的是在內部類中直接控制局部變量和引用,但是java這么整我們就不高興了,我在內部類中整半天想着是在操作外部變量,結果你給整個副本給我,我搞半天丫是整我自己的東西啊?要是java不這么整吧,由破壞了封裝性--------你個局部內部類牛啊,啥都沒有還能看局部變量呢。這不是java風格,肯定不能這么干。這咋整呢?
想想,類的封裝性咱們一定是要遵守的,不能破壞大局啊。但又要保證兩個東西是一模一樣的,包括對象和普通變量,那就使用final嘛,當傳遞普通變量的之前我把它變成一個常量給你,當傳遞引用對象的時候加上final就聲明了這個引用就只能指着這一個對象了。這樣就保證了內外統一。

 

 

轉:https://segmentfault.com/a/1190000002735907


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM