爲什麼匿名內部類只能訪問其所在方法中的final類型的局部變量?

匿名內部類不能訪問外部類方法中的局部變量,除非變量被聲明爲final類型

  1. 這裏所說的“匿名內部類”主要是指在其外部類的成員方法內定義,同時完成實例化的類,若其訪問該成員方法中的局部變量,局部變量必須要被final修飾。
  2. 原因是編譯程序實現上的困難:內部類對象的生命週期會超過局部變量的生命週期。局部變量的生命週期:當該方法被調用時,該方法中的局部變量在棧中被創建,當方法調用結束時,退棧,這些局部變量全部死亡。而內部類對象生命週期與其它類一樣:自創建一個匿名內部類對象,系統爲該對象分配內存,直到沒有引用變量指向分配給該對象的內存,它纔會死亡(被JVM垃圾回收)。所以完全可能出現的一種情況是:成員方法已調用結束,局部變量已死亡,但匿名內部類的對象仍然活着。
  3. 如果匿名內部類的對象訪問了同一個方法中的局部變量,就要求只要匿名內部類對象還活着,那麼棧中的那些它要所訪問的局部變量就不能“死亡”。
  4. 解決方法:匿名內部類對象可以訪問同一個方法中被定義爲final類型的局部變量。定義爲final後,編譯程序的實現方法:對於匿名內部類對象要訪問的所有final類型局部變量,都拷貝成爲該對象中的一個數據成員。這樣,即使棧中局部變量已死亡,但被定義爲final類型的局部變量的值永遠不變,因而匿名內部類對象在局部變量死亡後,照樣可以訪問final類型的局部變量,因爲它自己拷貝了一份,且與原局部變量的值始終一致。

最後,Java 8更加智能:如果局部變量被匿名內部類訪問,那麼該局部變量相當於自動使用了final修飾。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章