java 獲得列舉中的值
語法(定義)
建立列舉型別要使用 enum 關鍵字,隱含了所建立的型別都是 java.lang.Enum 類的子類(java.lang.Enum 是一個抽象類)。列舉型別符合通用模式 Class Enum<E extends Enum<E>>
,而 E
表示列舉型別的名稱。列舉型別的每一個值都將對映到 protected
Enum(String name, int ordinal)
建構函式中,在這裡,每個值的名稱都被轉換成一個字串,並且序數設定表示了此設定被建立的順序。
public enum Day { MON, TUE, WED, THU, FRI, SAT, SUN; public static void main(String[] args) { for(Day day:Day.values()){ System.out.println( day.toString() ); } Day mon= Day.MON; switch (mon) { case MON: System.out.println( "MON" ); break; case TUE: System.out.println( "TUE" ); break; default: break; } //compareTo(E o ) 比較此列舉與指定物件的順序 switch (mon.compareTo(Day.TUE)) { case -1: System.out.println("MON 在 TUE 之前"); break; case 1: System.out.println("MON 在 TUE 之後"); break; default: System.out.println("MON 與 TUE 在同一位置"); break; } //Class<E> getDeclaringClass() 返回與此列舉常量的列舉型別相對應的 Class 物件(全限定名)。 System.out.println("getDeclaringClass(): " + mon.getDeclaringClass().getName()); //String name() 返回此列舉常量的名稱,在其列舉宣告中對其進行宣告。 System.out.println("name(): " + mon.name()); //String toString() 返回列舉常量的名稱 System.out.println("toString(): " + mon.toString()); //int ordinal() 返回列舉常量的序數(它在列舉宣告中的位置,其中初始常量序數為零) System.out.println("ordinal(): " + mon.ordinal()); //static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) 返回帶指定名稱的指定列舉型別的列舉常量。 System.out.println( Day.valueOf( Day.class, "MON" ) ); // EnumSet的使用 EnumSet<Day> weekSet = EnumSet.allOf(Day.class); for (Day day : weekSet) { System.out.println(day); } // EnumMap的使用 EnumMap<Day, String> weekMap = new EnumMap<Day, String>(Day.class); weekMap.put(Day.MON, "星期一"); weekMap.put(Day.TUE, "星期二"); for (Iterator<Entry<Day, String>> iter = weekMap.entrySet().iterator(); iter.hasNext();) { Entry<Day, String> entry = iter.next(); System.out.println(entry.getKey().name() + ":" + entry.getValue()); } } }
MON, TUE, WED, THU, FRI, SAT, SUN; 這段程式碼實際上呼叫了7次 Enum(String name, int ordinal):
new Enum<Day>( "MON" , 0 );
new Enum<Day>( "TUE" , 1 );
new Enum<Day>( "WED" , 2 );
...
...
|
原理分析
enum 的語法結構儘管和 class 的語法不一樣,但是經過編譯器編譯之後產生的是一個class檔案。該class檔案經過反編譯可以看到實際上是生成了一個類,該類繼承了java.lang.Enum<E>。Day經過反編譯之後得到的內容如下:
public class com.test.Day extends java.lang.Enum{
public static final com.test.DayMON;
public static final com.test.DayTUE;
public static final com.test.DayWED;
public static final com.test.DayTHU;
public static final com.test.DayFRI;
public static final com.test.DaySAT;
public static final com.test.DaySUN;
static {};
public int getValue();
public boolean isRest();
public static com.test.Day[]
values();
public static com.test.DayvalueOf(java.lang.String);
com.test.Day(java.lang.String,
int , int ,
com.test.Day);
}
|
所以,實際上 enum 就是一個 class,只不過 java 編譯器幫我們做了語法的解析和編譯而已。
總結
可以把 enum 看成是一個普通的 class,它們都可以定義一些屬性和方法,不同之處是:enum 不能使用 extends 關鍵字繼承其他類,因為 enum 已經繼承了 java.lang.Enum(java是單一繼承).
LoginLimitType列舉類就是class,而且是一個不可以被繼承的final類。其列舉值(NO,YES...)都是Color型別的類靜態常量
(1) 構造器只是在構造列舉值的時候被呼叫。構造器只能私有private,這樣可以保證外部程式碼無法新構造列舉類的例項
(2) NO("0", "不允許") 其實就是呼叫了一個建構函式,列舉類中建構函式須給出
public enum LoginLimitType {
NO("0", "不允許"),YES("1", "允許");
private String code;
private String descs;
LoginLimitType(String code, String descs) {
this.code = code;
this.descs = descs;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDescs() {
return descs;
}
public void setDescs(String descs) {
this.descs = descs;
}
public static String getDesc(Integer value){
for (LoginLimitType lt : LoginLimitType.values()) {
if(lt.code.equals( value)){
return lt.descs;
}
}
return null;
}
}