1. 程式人生 > >java枚舉怎麽用的

java枚舉怎麽用的

data- 屬性 原因 引入 ref data 生成 copy 類型


package com.pingan.property.icore.pap.common.constants;

/**
*
*/
public enum UMAuthStatusEnum implements BaseEnumI {

// UM驗證失敗的幾種原因
AUTHORIZATION_IS_NULL("0", "header auth信息為空"),
UM_API_FAILED("1", "um系統API調用失敗");

String code;
String desc;

private UMAuthStatusEnum(String code, String desc) {
this.code = code;

this.desc = desc;
}

@Override
public void setCode(String code) {
this.code = code;
}

@Override
public String getCode() {
return this.code;
}

@Override
public void setDesc(String desc) {
this.desc = desc;
}

@Override
public String getDesc() {
return this.desc;
}
}

Java 枚舉7常見種用法

用法一:常量

在JDK1.5 之前,我們定義常量都是: publicstaticfianl.... 。現在好了,有了枚舉,可以把相關的常量分組到一個枚舉類型裏,而且枚舉提供了比常量更多的方法。

Java代碼
  1. public enum Color {
  2. RED, GREEN, BLANK, YELLOW
  3. }

用法二:switch

JDK1.6之前的switch語句只支持int,char,enum類型,使用枚舉,能讓我們的代碼可讀性更強。

Java代碼
  1. enum Signal {
  2. GREEN, YELLOW, RED
  3. }
  4. public class TrafficLight {
  5. Signal color = Signal.RED;
  6. public void change() {
  7. switch (color) {
  8. case RED:
  9. color = Signal.GREEN;
  10. break;
  11. case YELLOW:
  12. color = Signal.RED;
  13. break;
  14. case GREEN:
  15. color = Signal.YELLOW;
  16. break;
  17. }
  18. }
  19. }

用法三:向枚舉中添加新方法

如果打算自定義自己的方法,那麽必須在enum實例序列的最後添加一個分號。而且 Java 要求必須先定義 enum 實例。

Java代碼
  1. public enum Color {
  2. RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
  3. // 成員變量
  4. private String name;
  5. private int index;
  6. // 構造方法
  7. private Color(String name, int index) {
  8. this.name = name;
  9. this.index = index;
  10. }
  11. // 普通方法
  12. public static String getName(int index) {
  13. for (Color c : Color.values()) {
  14. if (c.getIndex() == index) {
  15. return c.name;
  16. }
  17. }
  18. return null;
  19. }
  20. // get set 方法
  21. public String getName() {
  22. return name;
  23. }
  24. public void setName(String name) {
  25. this.name = name;
  26. }
  27. public int getIndex() {
  28. return index;
  29. }
  30. public void setIndex(int index) {
  31. this.index = index;
  32. }
  33. }

用法四:覆蓋枚舉的方法

下面給出一個toString()方法覆蓋的例子。

Java代碼
  1. public enum Color {
  2. RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
  3. // 成員變量
  4. private String name;
  5. private int index;
  6. // 構造方法
  7. private Color(String name, int index) {
  8. this.name = name;
  9. this.index = index;
  10. }
  11. //覆蓋方法
  12. @Override
  13. public String toString() {
  14. return this.index+"_"+this.name;
  15. }
  16. }

用法五:實現接口

所有的枚舉都繼承自java.lang.Enum類。由於Java 不支持多繼承,所以枚舉對象不能再繼承其他類。

Java代碼
  1. public interface Behaviour {
  2. void print();
  3. String getInfo();
  4. }
  5. public enum Color implements Behaviour{
  6. RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
  7. // 成員變量
  8. private String name;
  9. private int index;
  10. // 構造方法
  11. private Color(String name, int index) {
  12. this.name = name;
  13. this.index = index;
  14. }
  15. //接口方法
  16. @Override
  17. public String getInfo() {
  18. return this.name;
  19. }
  20. //接口方法
  21. @Override
  22. public void print() {
  23. System.out.println(this.index+":"+this.name);
  24. }
  25. }

用法六:使用接口組織枚舉

Java代碼
  1. public interface Food {
  2. enum Coffee implements Food{
  3. BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
  4. }
  5. enum Dessert implements Food{
  6. FRUIT, CAKE, GELATO
  7. }
  8. }

用法七:關於枚舉集合的使用

java.util.EnumSet和java.util.EnumMap是兩個枚舉集合。EnumSet保證集合中的元素不重復;EnumMap中的 key是enum類型,而value則可以是任意類型。關於這個兩個集合的使用就不在這裏贅述,可以參考JDK文檔。

關於枚舉的實現細節和原理請參考:

參考資料:《ThinkingInJava》第四版

下文轉自http://blog.csdn.net/u014527058/article/details/52751488 感謝作者

枚舉(enum),是指一個經過排序的、被打包成一個單一實體的項列表。一個枚舉的實例可以使用枚舉項列表中任意單一項的值。枚舉在各個語言當中都有著廣泛的應用,通常用來表示諸如顏色、方式、類別、狀態等等數目有限、形式離散、表達又極為明確的量。Java從JDK5開始,引入了對枚舉的支持。

在枚舉出現之前,如果想要表示一組特定的離散值,往往使用一些常量。例如:

[java] view plain copy
  1. package com.fhp.enumexample;
  2. public class Entity {
  3. public static final int VIDEO = 1;//視頻
  4. public static final int AUDIO = 2;//音頻
  5. public static final int TEXT = 3;//文字
  6. public static final int IMAGE = 4;//圖片
  7. private int id;
  8. private int type;
  9. public int getId() {
  10. return id;
  11. }
  12. public void setId(int id) {
  13. this.id = id;
  14. }
  15. public int getType() {
  16. return type;
  17. }
  18. public void setType(int type) {
  19. this.type = type;
  20. }
  21. }

當然,常量也不僅僅局限於int型,諸如char和String等也是不在少數。然而,無論使用什麽樣的類型,這樣做都有很多的壞處。這些常量通常都是連續、有無窮多個值的量,而類似這種表示類別的量則是離散的,並且通常情況下只有有限個值。用連續的量去表示離散量,會產生很多問題。例如,針對上述的Entity類,如果要對Entity對象的type屬性進行賦值,一般會采用如下方法:

[java] view plain copy
  1. Entity e = new Entity();
  2. e.setId(10);
  3. e.setType(2);

這樣做的缺點有:(1)代碼可讀性差、易用性低。由於setType()方法的參數是int型的,在閱讀代碼的時候往往會讓讀者感到一頭霧水,根本不明白這個2到底是什麽意思,代表的是什麽類型。當然,要保證可讀性,還有這樣一個辦法:

[java] view plain copy
  1. e.setType(Entity.AUDIO);


而這樣的話,問題又來了。這樣做,客戶端必須對這些常量去建立理解,才能了解如何去使用這個東西。說白了,在調用的時候,如果用戶不到Entity類中去看看,還真不知道這個參數應該怎麽傳、怎麽調。像是setType(2)這種用法也是在所難免,因為它完全合法,不是每個人都能夠建立起用常量名代替數值,從而增加程序可讀性、降低耦合性的意識。

(2)類型不安全。在用戶去調用的時候,必須保證類型完全一致,同時取值範圍也要正確。像是setType(-1)這樣的調用是合法的,但它並不合理,今後會為程序帶來種種問題。也許你會說,加一個有效性驗證嘛,但是,這樣做的話,又會引出下面的第(3)個問題。

(3)耦合性高,擴展性差。假如,因為某些原因,需要修改Entity類中常量的值,那麽,所有用到這些常量的代碼也就都需要修改——當然,要仔細地修改,萬一漏了一個,那可不是開玩笑的。同時,這樣做也不利於擴展。例如,假如針對類別做了一個有效性驗證,如果類別增加了或者有所變動,則有效性驗證也需要做對應的修改,不利於後期維護。


枚舉就是為了這樣的問題而誕生的。它們給出了將一個任意項同另一個項相比較的能力,並且可以在一個已定義項列表中進行叠代。枚舉(在Jave中簡稱為enum)是一個特定類型的類。所有枚舉都是Java中的新類java.lang.Enum的隱式子類。此類不能手工進行子類定義。一個簡單的枚舉可以是這樣:

[java] view plain copy
  1. package com.fhp.enumexample;
  2. public enum TypeEnum {
  3. VIDEO, AUDIO, TEXT, IMAGE
  4. }

上面的Entity類就可以改成這樣:

[java] view plain copy
  1. package com.fhp.enumexample;
  2. public class Entity {
  3. private int id;
  4. private TypeEnum type;
  5. public int getId() {
  6. return id;
  7. }
  8. public void setId(int id) {
  9. this.id = id;
  10. }
  11. public TypeEnum getType() {
  12. return type;
  13. }
  14. public void setType(TypeEnum type) {
  15. this.type = type;
  16. }
  17. }


在為Entity對象賦值的時候,就可以這樣:

[java] view plain copy
  1. Entity e = new Entity();
  2. e.setId(10);
  3. e.setType(TypeEnum.AUDIO);


怎麽看,都是好了很多。在調用setType()時,可選值只有四個,否則會出現編譯錯誤,因此可以看出,枚舉是類型安全的,不會出現取值範圍錯誤的問題。同時,客戶端不需要建立對枚舉中常量值的了解,使用起來很方便,並且可以容易地對枚舉進行修改,而無需修改客戶端。如果常量從枚舉中被刪除了,那麽客戶端將會失敗並且將會收到一個錯誤消息。枚舉中的常量名稱可以被打印,因此除了僅僅得到列表中項的序號外還可以獲取更多信息。這也意味著常量可用作集合的名稱,例如HashMap。



因為在Java中一個枚舉就是一個類,它也可以有屬性和方法,並且實現接口。只是所有的枚舉都繼承自java.lang.Enum類,因此enum不可以再繼承其他的類。

下面給出在枚舉中聲明屬性和方法的示例:

[java] view plain copy
  1. package com.fhp.enumexample;
  2. public enum TypeEnum {
  3. VIDEO(1), AUDIO(2), TEXT(3), IMAGE(4);
  4. int value;
  5. TypeEnum(int value) {
  6. this.value = value;
  7. }
  8. public int getValue() {
  9. return value;
  10. }
  11. }


在這個枚舉中,每個枚舉的值都有一個對應的int型字段,而且不同的枚舉值也會有不同的int數值。同時,它和普通的類一樣,可以聲明構造器和各種各樣的方法。如:

[java] view plain copy
  1. TypeEnum type = TypeEnum.TEXT;//type的value屬性值為3。
  2. System.out.println(type.getValue());//屏幕輸出3。

如果要為每個枚舉值指定屬性,則在枚舉中必須聲明一個參數為屬性對應類型的構造方法(不能是public)。否則編譯器將給出The constructor TypeEnum(int, String) is undefined的錯誤。在此例中,屬性為int型,因此構造方法應當為int型。除此之外,還可以為枚舉指定多個屬性,如:

[java] view plain copy
  1. package com.fhp.enumexample;
  2. public enum TypeEnum {
  3. VIDEO(1, "視頻"), AUDIO(2, "音頻"), TEXT(3, "文本"), IMAGE(4, "圖像");
  4. int value;
  5. String name;
  6. TypeEnum(int value, String name) {
  7. this.value = value;
  8. this.name = name;
  9. }
  10. public int getValue() {
  11. return value;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. }


enum還內置了許多方法,常用的如下:

int compareTo(E o)
比較此枚舉與指定對象的順序。


Class<E> getDeclaringClass()
返回與此枚舉常量的枚舉類型相對應的 Class 對象。


String name()
返回此枚舉常量的名稱,在其枚舉聲明中對其進行聲明。


int ordinal()
返回枚舉常量的序數(它在枚舉聲明中的位置,其中初始常量序數為零)。


String toString()
返回枚舉常量的名稱,它包含在聲明中。


static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
返回帶指定名稱的指定枚舉類型的枚舉常量。


static T[] values()

返回該枚舉的所有值。

現在,假設要為該枚舉實現一個根據整數值生成枚舉值的方法,可以這樣做:

[java] view plain copy
  1. package com.fhp.enumexample;
  2. public enum TypeEnum {
  3. VIDEO(1, "視頻"), AUDIO(2, "音頻"), TEXT(3, "文本"), IMAGE(4, "圖像");
  4. int value;
  5. String name;
  6. TypeEnum(int value, String name) {
  7. this.value = value;
  8. this.name = name;
  9. }
  10. public int getValue() {
  11. return value;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public TypeEnum getByValue(int value) {
  17. for(TypeEnum typeEnum : TypeEnum.values()) {
  18. if(typeEnum.value == value) {
  19. return typeEnum;
  20. }
  21. }
  22. throw new IllegalArgumentException("No element matches " + value);
  23. }
  24. }


getByValue(int)即為整數值轉枚舉值的方法。調用values()方法獲取到該枚舉下的所有值,然後遍歷該枚舉下面的每個值和給定的整數是否匹配,若匹配直接返回,若無匹配值則拋出IllegalArgumentException異常,表示參數不合法,兼有有效性驗證的作用。

綜上,我們可以看到,在JDK5中新引入的枚舉完美地解決了之前通過常量來表示離散量所帶來的問題,大大加強了程序的可讀性、易用性和可維護性,並且在此基礎之上又進行了擴展,使之可以像類一樣去使用,更是為Java對離散量的表示上升了一個臺階。因此,如果在Java中需要表示諸如顏色、方式、類別、狀態等等數目有限、形式離散、表達又極為明確的量,應當盡量舍棄常量表示的做法,而將枚舉作為首要的選擇。

java枚舉怎麽用的