1. 程式人生 > >為什麼匿名內部類和區域性內部類只能訪問被final修飾的區域性變數?

為什麼匿名內部類和區域性內部類只能訪問被final修飾的區域性變數?

匿名內部類是形如下面程式碼中的類(Inner):

 

匿名內部類必須繼承一個父類或實現一個介面,但最多隻能實現一個介面。

上圖中,匿名內部類的父類就是Outer類。

區域性內部類是定義在方法中、程式碼塊中、構造器中的類。

形如下圖中的類:

 

 

那麼為什麼匿名內部類和區域性內部類只能訪問被final修飾的區域性變數呢?

根本原因是內部類的生命週期可能會超過區域性變數的生命週期。區域性變數的生命週期是當呼叫方法f()的時候,java虛擬機器會將區域性變數壓入棧中(即區域性變數產生),當方法f()執行結束後,java虛擬機器就會將區域性變量出棧(即區域性變數銷燬);但此時,內部類物件可能還存在,如果內部類物件此時去訪問區域性變數,那麼就會出問題。解決辦法就是把匿名內部類或區域性內部類要訪問的區域性變數複製一份作為內部類物件的成員變數;這樣當局部變數在棧中銷燬以後,內部類還能訪問區域性變數。但是這樣做會有一個問題,那就是必須時時刻刻保證複製的那一份區域性變數的值和原來的區域性變數的值相同,但是這樣做是很困難的;於是,java中乾脆就不允許內部類要訪問的區域性變數的值發生改變,也就是將這些區域性變數用final修飾。(用final修飾的區域性變數的值不能改變,只能是初始值。)