在第一次學習面向對象編程時,我記得最深的一句話就是「萬物皆對象」。因而我一直秉承着這個思想努力的學習着JAVA,直到學習到枚舉(Enum)時,看着它頗爲奇怪的語法……我一直在想,這TM是個什麼鬼???當時學習OOP時也是被類啊接口什麼的整的有點昏頭轉向的因而就把這個小細節忽略掉了。後來到了公司工做後慢慢的又須要用上枚舉了,看着它一副神祕兮兮的樣子我仍是決定要好好的深挖一下!如下連接是瞭解枚舉時所參考的博客。如發現本文有錯誤或知識遺漏歡迎在評論中指正!java
反編譯那些事兒(二)—枚舉的反編譯:http://blog.csdn.net/gaohuanjie/article/details/18140279數據庫
JAVA枚舉與常量類的區別:http://blog.csdn.net/tanqian351/article/details/53736628編程
1)歷史數組
2)語法解析工具
3)枚舉的好處以及與常量類的區別性能
4)枚舉經常使用方法學習
枚舉是JDK1.5版本新增的特性(泛型、For-each等現在被普遍應用的特性也是由JDK1.5時所新增的),另外到了JDK1.6後switch語句支持枚舉類型。this
1.最最最簡單版spa
public enum ColorEnum { RED,BLUE,GREEN }
經過工具解析class後得到的源代碼(工具參考上面的連接).net
public final class ColorEnum extends Enum { //返回存儲枚舉實例的數組的副本。values()方法一般用於foreach循環遍歷枚舉常量。 public static ColorEnum[] values() { return (ColorEnum[])$VALUES.clone(); } //根據實例名獲取實例 public static ColorEnum valueOf(String s) { return (ColorEnum)Enum.valueOf(ColorEnum, s); } //私有構造方法,這裏調用了父類的構造方法,其中參數s對應了常量名,參數i表明枚舉的一個順序(這個順序與枚舉的聲明順序對應,用於oridinal()方法返回順序值) private ColorEnum(String s, int i) { super(s, i); } //咱們定義的枚舉在這裏聲明瞭三個 ColorEnum的常量對象引用,對象的實例化在static靜態塊中 public static final ColorEnum RED; public static final ColorEnum BLUE; public static final ColorEnum GREEN; //將全部枚舉的實例存放在數組中 private static final ColorEnum $VALUES[]; static { RED = new ColorEnum("RED", 0); BLUE = new ColorEnum("BLUE", 1); GREEN = new ColorEnum("GREEN", 2); //將全部枚舉的實例存放在數組中 $VALUES = (new ColorEnum[] { RED, BLUE, GREEN }); } }
2.如今咱們在枚舉類中增長本身的字段以及一些輔助方法,代碼以下:
public enum ColorEnum { RED("red","紅色"),GREEN("green","綠色"),BLUE("blue","藍色"); //防止字段值被修改,增長的字段也統一final表示常量 private final String key; private final String value; private ColorEnum(String key,String value){ this.key = key; this.value = value; } //根據key獲取枚舉 public static ColorEnum getEnumByKey(String key){ if(null == key){ return null; } for(ColorEnum temp:ColorEnum.values()){ if(temp.getKey().equals(key)){ return temp; } } return null; } public String getKey() { return key; } public String getValue() { return value; } }
老規矩,反編譯看看變化?(其實也就看看static靜態塊和構造方法有什麼變化就行了)
public final class ColorEnum extends Enum { public static ColorEnum[] values() { return (ColorEnum[])$VALUES.clone(); } public static ColorEnum valueOf(String s) { return (ColorEnum)Enum.valueOf(ColorEnum, s); } //構造方法在原基礎上加上咱們新增的兩個形參 private ColorEnum(String s, int i, String s1, String s2) { super(s, i); key = s1; value = s2; } //自定義方法,經過key值得到對應的枚舉對象 public static ColorEnum getEnumByKey(String s) { if(null == s) return null; ColorEnum acolorenum[] = values(); int i = acolorenum.length; for(int j = 0; j < i; j++) { ColorEnum colorenum = acolorenum[j]; if(colorenum.getKey().equals(s)) return colorenum; } return null; } public String getKey() { return key; } public String getValue() { return value; } public static final ColorEnum RED; public static final ColorEnum GREEN; public static final ColorEnum BLUE; //咱們自定義的兩個字段 private final String key; private final String value; private static final ColorEnum $VALUES[]; static { RED = new ColorEnum("RED", 0, "red", "\u7EFE\u3223\u58CA"); GREEN = new ColorEnum("GREEN", 1, "green", "\u7F01\u80EF\u58CA"); BLUE = new ColorEnum("BLUE", 2, "blue", "\u9483\u6FCA\u58CA"); $VALUES = (new ColorEnum[] { RED, GREEN, BLUE }); } }
1)枚舉型能夠直接與數據庫打交道,我一般使用varchar類型存儲,對應的是枚舉的常量名。(數據庫中好像也有枚舉類型,不過也沒用過)
2) switch語句支持枚舉型,當switch使用int、String類型時,因爲值的不穩定性每每會有越界的現象,對於這個的處理每每只能經過if條件篩選以及default模塊來處理。而使用枚舉型後,在編譯期間限定類型,不容許發生越界的狀況
3) 當你使用常量類時,每每得經過equals去判斷二者是否相等,使用枚舉的話因爲常量值地址惟一,能夠用==直接對比,性能會有提升
4) 常量類編譯時,是直接把常量的值編譯到類的二進制代碼裏,常量的值在升級中變化後,須要從新編譯引用常量的類,由於裏面存的是舊值。枚舉類編譯時,沒有把常量值編譯到代碼裏,即便常量的值發生變化,也不會影響引用常量的類。
5)枚舉類編譯後默認爲final class,不容許繼承可防止被子類修改。常量類可被繼承修改、增長字段等,容易致使父類的不兼容。
………………歡迎補充!
總結:常量的定義在開發中是必不可少的,雖然不管是經過常量類定義常量仍是枚舉定義常量均可以知足常量定義的需求。但我的建議最好是使用枚舉類型。
1.values()獲取存儲枚舉中全部常量實例的數組。常配合foreach完成遍歷
for(ColorEnum temp:ColorEnum.values()){ System.out.println(temp); }
運行結果:
RED
GREEN
BLUE
2.構造方法,枚舉的構造方法只能用private修飾符修飾,緣由就不須要解釋了……
3.valueOf()經過常量名獲取對應的枚舉實例。
ColorEnum red = ColorEnum.valueOf("RED"); System.out.println(red);