「JAVA」Java 內(nèi)部類詳解,局部的、靜態(tài)的、匿名的、實例的

內(nèi)部類

內(nèi)部類

Java 類中的可以定義的成員有:字段、方法、內(nèi)部類,內(nèi)部類是定義在類結(jié)構(gòu)中的另一個類,因為定義在類的內(nèi)部,故稱為內(nèi)部類。

Java 內(nèi)部類

在上述的代碼示例中,就可以將InnerClass稱之為OuterClass的內(nèi)部類。

為什么使用內(nèi)部類:

1. 增強面向?qū)ο蟮姆庋b,可以把一些不想對外的實現(xiàn)細節(jié)封裝在內(nèi)部類中,從而隱藏在外部類之內(nèi),限制了其他對象的直接訪問。

2. 內(nèi)部類能提高代碼的可讀性和可維護性。

3. 內(nèi)部類可以直接訪問外部類的成員。

LinkedList 中的內(nèi)部類實現(xiàn)

在Java中的LinkedList的源碼中,使用一個內(nèi)部類Node來封裝鏈表列表中的每一個節(jié)點,在節(jié)點中存儲了當前節(jié)點的值,上一個節(jié)點,下一個節(jié)點這些信息;而這些信息是不能外部對象直接讀取和使用的,因此,使用內(nèi)部類封裝隱藏是一個不錯的選擇。

內(nèi)部類的分類:

內(nèi)部類根據(jù)使用的修飾符的不同,或者定義的位置的不同,分成四種類型;

1. 實例內(nèi)部類:內(nèi)部類沒有使用static修飾,也就是非靜態(tài)內(nèi)部類,定義在類中,方法之外;

2. 靜態(tài)內(nèi)部類:內(nèi)部類使用了static修飾,定義在類中,方法之外,并且使用static修飾;

3. 局部內(nèi)部類:在方法中定義的內(nèi)部類;

4. 匿名內(nèi)部類:匿名內(nèi)部類屬于局部內(nèi)部類的特殊情況,適合于僅使用一次使用的類;


對于每個內(nèi)部類來說,經(jīng)過JVM編譯后都會生成獨立的.class字節(jié)碼文件,因為JVM會為每一個類產(chǎn)生各自的字節(jié)碼文件。

1. 成員內(nèi)部類:外部類名$內(nèi)部類名字

2. 局部內(nèi)部類:外部類名$數(shù)字內(nèi)部類名稱

3. 匿名內(nèi)部類:外部類名$數(shù)字

幾種內(nèi)部類的區(qū)別與聯(lián)系

內(nèi)部類其實就是外部類的一個成員,跟字段、方法一樣的存在,那么內(nèi)部類可以使用訪問控制修飾符:public/缺省/protected/private和static修飾符修飾。


實例內(nèi)部類

實例內(nèi)部類

沒有使用static修飾的內(nèi)部類,實例內(nèi)部類屬于外部類的對象,不屬于外部類本身;可以通過外部類對象來訪問。其特點是:

1. 在實例化內(nèi)部類之前,必須存在外部類對象,因為要通過外部類對象創(chuàng)建內(nèi)部類對象,所以存在內(nèi)部類對象時,一定存在外部類對象;

????????OutterClass.InnerClass in = new OutterClass().new InnerClass();

2. 實例內(nèi)部類的實例自動持有外部類的實例的引用,所以內(nèi)部類可以直接訪問外部類成員;

3. 外部類中不能直接訪問內(nèi)部類的成員,必須通過內(nèi)部類的實例去訪問;

4. 實例內(nèi)部類中不能定義靜態(tài)成員,只能定義實例成員(非靜態(tài)成員);

5. 如果實例內(nèi)部類和外部類存在同名的字段或方法abc,那么在內(nèi)部類中:

????????this.abc:表示訪問內(nèi)部類成員;

????????外部類.this.abc:表示訪問外部類成員;

實例內(nèi)部類代碼案例如下:

實例內(nèi)部類代碼案例


靜態(tài)內(nèi)部類

靜態(tài)內(nèi)部類:使用static修飾的內(nèi)部類,這點有別于實例內(nèi)部類,需要特別注意。其特點是:

1. 靜態(tài)內(nèi)部類的實例不會自動持有外部類的特定實例的引用,因此在創(chuàng)建內(nèi)部類的實例時,不必創(chuàng)建外部類的實例。

????????OutterClass.InnerClass in = new OutterClass.InnerClass();

2. 靜態(tài)內(nèi)部類可以直接訪問外部類的靜態(tài)成員,如果要訪問外部類的實例成員,還是必須通過外部類的實例去訪問。

3. 在靜態(tài)內(nèi)部類中可以同時定義靜態(tài)成員和實例成員。

4. 外部類可以通過完整的類名直接訪問靜態(tài)內(nèi)部類的靜態(tài)成員。

靜態(tài)內(nèi)部類代碼案例如下:

靜態(tài)內(nèi)部類代碼案例


局部內(nèi)部類:在方法中定義的內(nèi)部類,其作用域范圍和當前方法及其當前方法的局部變量是同一個級別。不過局部內(nèi)部類使用的較少,在開發(fā)中也不推薦使用。

1. 不能使用public、private、protected、static等這些修飾符;

2. 局部內(nèi)部類只能在當前方法中使用,作用域范圍僅限于當前的方法中;

3. 局部內(nèi)部類和實例內(nèi)部類一樣,不能擁有靜態(tài)成員,但都可以訪問外部類的所有成員;

4. 局部內(nèi)部類訪問的局部變量必須使用final修飾,在Java8中是自動隱式加上final,但是依然是常量,值不能被改變;

為什么不推薦使用局部內(nèi)部類?因為如果當前方法不是main方法,那么當前方法調(diào)用完畢之后,當前方法的棧幀會被銷毀,方法內(nèi)部的局部變量的空間也會全部銷毀。

然而局部內(nèi)部類是定義在方法中的,在方法中會創(chuàng)建局部內(nèi)部類對象,局部內(nèi)部類對象會去訪問局部變量;如果當前方法被銷毀,局部內(nèi)部類對象還在堆內(nèi)存中,依然持有對局部變量的引用,但是方法被銷毀的時候方法中的局部變量卻被銷毀了。

此時就會出現(xiàn):在堆內(nèi)存中,一個對象引用著一個不存在的變量,為了避免該問題,可以使用final修飾局部變量,從而變成常量,使之永駐內(nèi)存空間,這樣即使方法被銷毀了,該局部變量也繼續(xù)存在在內(nèi)存中,對象可以繼續(xù)持有。

局部內(nèi)部類代碼案例如下:

局部內(nèi)部類代碼案例

匿名內(nèi)部類

匿名內(nèi)部類(Anonymous),是一個沒有名稱的局部內(nèi)部類,適合只使用一次的類。在開發(fā)中會經(jīng)常使用這樣的類,只需要定義一次,僅僅使用一次就可以不再使用了,此時就不應(yīng)該再定義在一個類來存儲其功能邏輯。比如在Android的事件處理中,不同的按鈕點擊之后產(chǎn)生的不同的響應(yīng)操作,首先選擇使用匿名內(nèi)部類。

匿名內(nèi)部類的語法格式:

匿名內(nèi)部類的語法

但是需要注意的是:匿名內(nèi)部類必須繼承一個父類或者實現(xiàn)一個接口,但其最多只能繼承一個父類或?qū)崿F(xiàn)一個接口。

匿名內(nèi)部類的特點:

1. 匿名內(nèi)部類本身沒有構(gòu)造器,但是會調(diào)用父類構(gòu)造器;

2. 匿名類盡管沒有構(gòu)造器,但是可以在匿名類中提供一段實例初始化代碼塊,JVM在調(diào)用父類構(gòu)造器后,會執(zhí)行該段代碼;

3. 內(nèi)部類處理可以繼承類之外,還可以實現(xiàn)接口;

匿名內(nèi)部類代碼案例如下:下述代碼是安卓中的按鈕點擊事件處理邏輯

安卓中的按鈕點擊事件處理邏輯

這個案例就很好的展示了內(nèi)部類的使用,并且在安卓開發(fā)中,這樣的實例會有很多。

完結(jié)。老夫雖不正經(jīng),但老夫一身的才華

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容