關于java Enum


java的枚舉類型聲明非常簡單净当,這里我們聲明一個只有兩個枚舉值的TypeB

public enum TypeB {
    A,B;
}

隨后編譯器生成TypeB.class文件,我們來研究下里面藏了什么

首先是靜態(tài)變量和靜態(tài)代碼塊:

{
  public static final testAnything.TypeB A;
    
  public static final testAnything.TypeB B;
    //聲明兩個TypeB的實例瓣戚,和我們聲明的枚舉值同名
  static {};
    flags: ACC_STATIC
    Code:
      stack=4, locals=0, args_size=0
         0: new           #1                  // class testAnything/TypeB
         3: dup           
         4: ldc           #13                 // String A
         6: iconst_0      
         7: invokespecial #14                 // Method "<init>":(Ljava/lang/String;I)V
        10: putstatic     #18                 // Field A:LtestAnything/TypeB;
         //調用Enum(String,int)方法球碉,生成TypeB.A
         
        13: new           #1                  // class testAnything/TypeB
        16: dup           
        17: ldc           #20                 // String B
        19: iconst_1      
        20: invokespecial #14                 // Method "<init>":(Ljava/lang/String;I)V
        23: putstatic     #21                 // Field B:LtestAnything/TypeB;
         //調用Enum(String,int)方法撞蜂,生成TypeA.B
         
        26: iconst_2      
        27: anewarray     #1                  // class testAnything/TypeB
        //生成一個長度為2的TypeB[]
        
        30: dup           
        31: iconst_0      
        32: getstatic     #18                 // Field A:LtestAnything/TypeB;
        35: aastore       
        36: dup           
        37: iconst_1      
        38: getstatic     #21                 // Field B:LtestAnything/TypeB;
        41: aastore       
        42: putstatic     #23                 // Field ENUM$VALUES:[LtestAnything/TypeB;
        //將A,B的值放入TypeB[]盲镶,并賦值給私有靜態(tài)變量ENUM$VALUE
        45: return        

上面這部分字節(jié)碼指令主要做了兩件事:

  1. 為兩個公共靜態(tài)變量A和B賦值
  2. 將A,B的值存入私有靜態(tài)變量ENUM$VALUES中

這里的ENUM$VALUES變量名是可變的侥袜,如果在enum類中聲明了同名的變量,編譯器選用其他變量名溉贿。

下面是values()靜態(tài)方法枫吧,它返回枚舉類型的所有枚舉值:


public static testAnything.TypeB[] values();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=5, locals=3, args_size=0
         0: getstatic     #25                 // Field ENUM$VALUES:[LtestAnything/TypeB;
         3: dup           
         4: astore_0      
         5: iconst_0      
         6: aload_0       
         7: arraylength   
         8: dup           
         9: istore_1      
        10: anewarray     #1                  // class testAnything/TypeB
        13: dup           
        14: astore_2      
        15: iconst_0      
        16: iload_1       
        17: invokestatic  #33                 // Method java/lang/System.arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V
        20: aload_2       
        21: areturn       
    

這個方法做的事只有一件,拷貝ENUM$VALUE并返回宇色。具體流程大家有興趣可以自己畫下運行棧和變量表九杂。

接下來是繼承自Enum類的valueOf方法:

public static testAnything.TypeB valueOf(java.lang.String);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: ldc           #1                  // class testAnything/TypeB
         2: aload_0       
         3: invokestatic  #41                 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
         6: checkcast     #1                  // class testAnything/TypeB
         9: areturn       
}

這個方法與它重寫的方法唯一的區(qū)別就是把返回值類型由Object變?yōu)門ypeB。

這樣宣蠕,我們就可以模擬寫出TypeB.java了:

public class TypeB extends Enum{
//上面的繼承會報錯例隆,不能顯式的繼承Enum
    public static TypeB A;
    public static TypeB B;
    
    private static TypeB[] ENUM$VALUE ;
    
    static{
        A = new Enum(A,0);
        B = new Enum(B,1);
        //上面的調用無法編譯通過,Enum的修飾符是protected
        TypeB[] newarr = new TypeB[2];
        newarr[0] = A;
        newarr[1] = B;
        ENUM$VALUE = newarr;
    }
    
    public static TypeB[] values(){
        int length = ENUM$VALUE.length;
        TypeB[] newArr = new TypeB[length];
        System.arraycopy(ENUM$VALUE, 0, newArr, 0, length);
        return newArr;
    }
    
    public static TypeB valueOf(String name){
        return (TypeB)Enum.valueOf(TypeB.class, name);
    }
    
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末抢蚀,一起剝皮案震驚了整個濱河市镀层,隨后出現的幾起案子,更是在濱河造成了極大的恐慌皿曲,老刑警劉巖唱逢,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異谷饿,居然都是意外死亡惶我,警方通過查閱死者的電腦和手機妈倔,發(fā)現死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門博投,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人盯蝴,你說我怎么就攤上這事毅哗。” “怎么了捧挺?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵虑绵,是天一觀的道長。 經常有香客問我闽烙,道長翅睛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任黑竞,我火速辦了婚禮捕发,結果婚禮上,老公的妹妹穿的比我還像新娘很魂。我一直安慰自己扎酷,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布遏匆。 她就那樣靜靜地躺著法挨,像睡著了一般谁榜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凡纳,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天窃植,我揣著相機與錄音,去河邊找鬼惫企。 笑死撕瞧,一個胖子當著我的面吹牛,可吹牛的內容都是我干的狞尔。 我是一名探鬼主播丛版,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼偏序!你這毒婦竟也來了页畦?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤研儒,失蹤者是張志新(化名)和其女友劉穎豫缨,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體端朵,經...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡好芭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了冲呢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舍败。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖敬拓,靈堂內的尸體忽然破棺而出邻薯,到底是詐尸還是另有隱情,我是刑警寧澤乘凸,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布厕诡,位于F島的核電站,受9級特大地震影響营勤,放射性物質發(fā)生泄漏灵嫌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一葛作、第九天 我趴在偏房一處隱蔽的房頂上張望寿羞。 院中可真熱鬧,春花似錦进鸠、人聲如沸稠曼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽霞幅。三九已至漠吻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間司恳,已是汗流浹背途乃。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扔傅,地道東北人耍共。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像猎塞,于是被迫代替她去往敵國和親试读。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容