java 局部內部類與final局部變量的思考

        這些天,看了一些書,有些代碼覺得寫得挺不錯。匿名內部裏雖然以前也學過,但是就自身來說,用得還是少。先貼出一段代碼。


        ArrayAsList類主要是提供了一個intArrayAsList方法,將int類型的數組轉換面list。初看,返回的list並不真正擁有int [] a,是在調用get(int index)方法的時候,才從a數組中拿出相應下標的值返回去。但是,數組也是對象,也是引用傳遞,能保證傳遞過來的int [] a數組不被回收嗎?如果被回收了,那再調用get(int index)不就拋異常了。對這個問題一時很困惑,於是在網上開始找資料。加上自己的一些調試,大致理解了其中的原因。

       我們都知道,在方法內部定義的局部變量,會在方法執行完後而回收。但是,在方法內部定義的類卻不一定在方法結束後而被回收,局部內部類的生命週期,是有可能比方法的生命週期長的。但是,如果方法執行結束,局部變量被回收,而在方法內部定義的內部類還存在,在內部類中調用了方法的局部變量,這時局部變量已經不存在,就會出錯 。

       對於內部類,默認有個對外部的引用。如果局部變量是個對象,不是基本類型,我們知道對象是在堆中分配內存的,基本類型是在方法棧中分配內存的。如果內部類引用的局部變量是引用類型的,就算方法執行完,方法棧被回收,內部類還保持對局部對象的引用,對象沒被回收,也還說得過去。但如果局部變量是基本類型呢?基本類型是在方法棧中分配內存的,方法執行完,基本類型的局部變量必然被彈棧,方法棧被回收,基本類型的局部變量消失,那麼我們內部類調用就會出錯。

      爲了解決這個問題,我們在方法內部定義的類,不管是匿名的還是非匿名的,如果要訪問方法內部的局部變量,包括參數變量,編譯器都要求我們的變量是final的。根據自己的調試,更堅信這一點是正確的。java的處理機制,是將內部類引用的局部變量做了一個拷貝,放到了內部類作爲內部類的一個成員。final定義的變量還是會像以前一樣,方法執行完,內存該被回收的還是回收,但這個拷貝,放在內部類裏,將會跟隨內部類的整個生命週期。

       

發佈了24 篇原創文章 · 獲贊 13 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章