Java 內部類及其原理


Java中實現內部類

Java 內部類

 

內部類相信大家都用過很多次了,就不說它是怎么用的了。

內部類

1.成員內部類

Java 內部類

 

需要注意的是, 當成員內部類擁有和外部類同名的成員變量或這方法時, 默認情況下訪問的是內部類的成員, 如要訪問外部類的同名成員, 需要使用以下形式:

外部類.this.成員變量
外部類.this.成員方法

內部類是依附外部類而存在的, 也就是說要創建成員內部類的對象,前提是創建一個外部類的對象,創建成員內部類的方式如下:

new Main().new Inner();

成員內部類可以擁有private訪問權限、protected訪問權限、public訪問權限、默認訪問權限。如用private修飾,則只能在外部類的內部訪問。

2.局部內部類

局部內部類是定義在一個方法或作用域中的類,它的訪問權限僅限於方法內或作用域內。

Java 內部類

 

局部內部類也可以返回,像這樣:

Java 內部類

 

3.匿名內部類

匿名內部類應該是我們平常使用最多的了,如下面創建線程:

Java 內部類

 

匿名內部類在編譯的時候有系統自動起名:Main$1

匿名內部類是沒有構造器的類,大部分用於繼承其他類或實現接口,並不需要增加額外的方法,只是對繼承方法的實現或是重寫

4.靜態內部類

靜態內部類也是定義在另一個類里面的類,只不過在類前加上了static。靜態內部類是不需要依賴於外部類的,與靜態成員變量類似。

Java 內部類

 

外部創建該靜態類時可以如下創建:

Main.Inner mi = new Main Inner();

內部類實現原理

內部類為什么能夠訪問外部類的成員?

定義內部類如下:

Java 內部類

 

使用javap命令進行反編譯。

編譯后得到Main.class Main$Inner.class兩個文件,反編譯Main$Inner.class文件如下:

Java 內部類

 

可以看到,內部類其實擁有外部類的一個引用,在構造函數中將外部類的引用傳遞進來。

匿名內部類為什么只能訪問局部的final變量?

其實可以這樣想,當方法執行完畢后,局部變量的生命周期就結束了,而局部內部類對象的生命周期可能還沒有結束,那么在局部內部類中訪問局部變量就不可能了,所以將局部變量改為final,改變其生命周期。

編寫代碼如下:

Java 內部類

 

這段代碼編譯為Main.class Main$1.class兩個文件,反編譯Main$1.class文件如下:

Java 內部類

 

可以看到,java將編譯時已經確定的值直接復制,進行替換,將無法確定的值放到了內部類的常量池中,並在構造函數中將其從常量池取出到字段中。

可以看出,java將局部變量m直接進行復制,所以其並不是原來的值,若在內部類中將m更改,局部變量的m值不會變,就會出現數據不一致,所以java就將其限制為final,使其不能進行更改,這樣數據不一致的問題就解決了。

匿名內部類為什么訪問外部類成員字段不用final?

上面說了,final關鍵字是為了解決數據不一致的問題,因為內部類中存有外部類的引用,所有對外部類中字段的修改都會真實的反映到外部類實例本身,所以不需要用final來修飾。


免責聲明!

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



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