枚舉類型在編譯器處理之后,是由一個(gè)final的繼承Enum類的類實(shí)現(xiàn)的。該類是一個(gè)實(shí)實(shí)在在存在的類。在該類當(dāng)中,編譯器還幫助我們生成了每個(gè)枚舉類型的實(shí)例對象,這些對象分別對應(yīng)枚舉中定義的每個(gè)枚舉類型本身。
java中的內(nèi)部類
定義:將一個(gè)類的定義放在另一個(gè)類的定義內(nèi)部,即為內(nèi)部類。
內(nèi)部類本質(zhì)上是java的一種"語法糖"。為什么這樣說呢?舉例說明,假設(shè)現(xiàn)在有如下代碼:
public class A {
? ? private int a;
? ? static class B {
? ? }
? ? class C {
? ? ? ? public void test(){
? ? ? ? ? ? int b? = a;
? ? ? ? }
? ? }
}
類A是一個(gè)普通的類,在他的內(nèi)部定義了兩個(gè)類B,以及C。從代碼結(jié)構(gòu)上來看,B類和C類為A類的內(nèi)部,但是在使用編譯器編譯之后,它們并不是一個(gè)類,而是會變成符合一定名稱規(guī)則的三個(gè)類
它在編譯之后會產(chǎn)生三個(gè).class文件,分別是:A.class, A$B.class, A$C.class. 因此,本質(zhì)上它們還是三個(gè)類,只是借助于java編譯器的語法糖支持,我們可以寫在一個(gè)類里面,從這個(gè)例子我們不難推斷出,在java 里任何一個(gè)類,無論是以怎樣的形式定義,在編譯之后生成字節(jié)碼文件之后,其必然是一個(gè)單獨(dú)存在的類。理解java的類加載機(jī)制的話對這句話理解起來就更加容易,java加載任何一個(gè)類的時(shí)候都是會首先從加載其class文件開始,若一個(gè)類不存在對應(yīng)的class文件,那么它必然無法被加載也無法被使用。
同時(shí),知道了上述知識之后,我們來看這樣兩個(gè)問題:
內(nèi)部類可以被繼承嗎?答案是肯定可以的,只是從java語法來說寫起來會稍微有點(diǎn)區(qū)別
內(nèi)部類的方法可以被覆蓋嗎?答案一樣是可以的。
為何java編譯器會支持定義內(nèi)部類這樣的使用方式,原因在于當(dāng)一個(gè)類定義在另一個(gè)類內(nèi)部之后,許多操作會變得簡單一些,比如一個(gè)內(nèi)部類可以直接訪問外部類的任何成員。為什么內(nèi)部類能直接訪問外部類的任何成員呢?原因在于java編譯器對內(nèi)部類的功能t提供了支持,讓我們再來看上述代碼反編譯回來的結(jié)果:
public class A {
? ? private int a;
? ? public A() {
? ? }
? ? class C {
? ? ? ? C() {
? ? ? ? }
? ? ? ? public void test() {
? ? ? ? ? ? int b = A.this.a;//通過類名加this關(guān)鍵字
? ? ? ? }
? ? }
? ? static class B {
? ? ? ? B() {
? ? ? ? }
? ? }
}
可以看到是通過類名跟上.this關(guān)鍵字實(shí)現(xiàn)的對外部成員的訪問,這相當(dāng)于是隱式的持有了一個(gè)外部類引用,即建立了一個(gè)內(nèi)部類和外部類之間的聯(lián)系。
同時(shí),這里我們需要注意這里的B類聲明成了static的類,C類則沒有。我們常常把用static修飾的內(nèi)部類成為嵌套類。
他們的區(qū)別在于,嵌套類與外圍類之間是沒有聯(lián)系的。這意味這創(chuàng)建嵌套類無需外部類,當(dāng)然,也不能從嵌套類的對象中訪問非靜態(tài)的外圍類對象。同時(shí),在嵌套類的內(nèi)部可以使用static關(guān)鍵字,而普通的內(nèi)部類不能使用static關(guān)鍵字。
用途:從代碼的組織結(jié)構(gòu)來說,使用內(nèi)部類可以把邏輯相關(guān)的類組織在一起。內(nèi)部類訪問外部類將非常方便,內(nèi)部類能訪問外圍對象的所有成員,且不需要任何特殊條件。但這不是最主要的原因,從設(shè)計(jì)角度出發(fā),使用內(nèi)部類最大的原因在于:每個(gè)內(nèi)部類可以獨(dú)立但繼承一個(gè)類,這意味著雖然java的類是單繼承的,但是通過使用內(nèi)部類,可以達(dá)到類似多重繼承的效果。因此,如果不需要解決多重繼承的問題,使用內(nèi)部類就并不是必須的了,因?yàn)槠渌木幋a方式都能實(shí)現(xiàn)一樣的效果。