對於要在程式中要表示有限種類的某事物,一般我們可以採用兩種方式,一是使用:public static final String 常量;二是使用enum來表示。一般而言前者簡單,但是不能夠很好的提供更多的資訊,而Java中的enum相比而言,卻十分的強大,而且更加的專業。
1. 最間C風格的enum:
/** * 資料來源的類別:master/slave */ public enum DataSources { MASTER0, MASTER1, SLAVE0, SLAVE1, SLAVE2, SLAVE2 }
這是最簡單的enum, 和C語言中的幾乎一樣。簡單簡潔但是功能也很弱。
2. enum 的本質
Java中的enum的本質是一個繼承java.lang.Enum的類。所以他就比C風格的enum更加的強大。它可以又屬性,方法,建構函式等等,下面看一個例子:
import org.apache.commons.lang.StringUtils; /** * 錯誤碼列舉*/ public enum ErrorCodeEnum { /** 系統異常 */ SYSTEM_ERROR("system_error", "系統異常"), /** 引數非法 */ ILLEGAL_ARGUMENT("illegal_argument", "引數非法"), /** 簽名非法 */ ILLEGAL_SIGN("illegal_sign", "簽名非法"),
// ... ...
/** 註冊碼非法 */ ILLEGAL_REG_CODE("illegal_reg_code", "註冊碼非法"); /** 列舉碼 */ private String code; /** 列舉描述 */ private String desc; private ErrorCodeEnum(String code, String desc) { this.code = code; this.desc = desc; } public String getCode() { return code; } public String getDesc() { return desc; } /** * 根據列舉碼獲取列舉 * @param code 列舉碼 * @return 列舉 */ public static final ErrorCodeEnum getByCode(String code) { if (StringUtils.isBlank(code)) { return null; } for (ErrorCodeEnum item : ErrorCodeEnum.values()) { if (StringUtils.equals(item.getCode(), code)) { return item; } } return null; } }
我們看到 ErrorCodeEnum 具有屬性 String code 和 String desc,並且具有一個私有的建構函式。原因是我們的列舉常量需要使用這個私有的建構函式的定義:SYSTEM_ERROR("system_error", "系統異常") 就是呼叫的列舉的私有建構函式:private ErrorCodeEnum(String code, String desc);所以其實ErrorCodeEnum 中定義的列舉常量 SYSTEM_ERROR, ILLEGAL_ARGUMENT 等其實就相當於 ErrorCodeEnum 的一個例項而已,因為它們是呼叫ErrorCodeEnum 的私有建構函式生成的。而 ErrorCodeEnum 的屬性 String code 和 String desc,是為了更好的提供更加詳細的錯誤資訊而定義的。而且在列舉ErrorCodeEnum中還可以定義其它的各種輔助方法。
所以列舉的本質是一個繼承與java.lang.Enum的類,列舉常量就是列舉的一個個的例項。列舉可以有屬性和方法,來強化列舉的功能。列舉一般而言在Java中不是很好理解,一般掌握了列舉背後的本質,那麼理解起來就毫無難度了。
3. 列舉的常用方法
public static void main(String[] args){ System.out.println(SYSTEM_ERROR.name()); System.out.println(SYSTEM_ERROR.ordinal()); System.out.println(SYSTEM_ERROR.toString()); for(ErrorCodeEnum e : ErrorCodeEnum.values()){ System.out.println(e.name()); System.out.println(e.getDesc()); } System.out.println(ErrorCodeEnum.SYSTEM_ERROR.name());
System.out.println(ErrorCodeEnum.valueOf(ErrorCodeEnum.class, "ILLEGAL_ARGUMENT")); }
String name() : Returns the name of this enum constant, exactly as declared in its enum declaration. 返回列舉常量宣告時的字串。
int ordinal() : 返回列舉常量的宣告時的順序位置,像陣列的索引一樣,從0開始。
valueOf(Class<T> enumType, String name) : 其實是從 列舉常量的字串到 列舉常量的轉換,相當於一個工廠方法。
name() 方法是從 列舉常量 到 字串的轉換,而 valueOf 是字串到 列舉常量的轉換。
values() : 該方法是一個隱式的方法,All the constants of an enum type can be obtained by calling the implicit public static T[] values()
method of that type. 用於遍歷列舉中的所有的列舉常量。
4. enum相關的資料結構:EnumMap, EnumSet 具體可以參考jdk文件。
5. enum 相對於 常量的優勢(略)