enum (enumeration)
, 是 JDK 1.5
中引入的新特性舍肠,在 java.lang
包中婶肩。
定義
創(chuàng)建枚舉類型使用 enum
關鍵字,創(chuàng)建的類型都是 java.lang.Enum(抽象類)
類的子類貌夕。枚舉類型符合通用模式 Class Enum<E extends Enum<E>>
, E
表示枚舉類型的名稱民镜。枚舉類型的每一個值都將映射到 protected Enum(String name, int ordinal)
構造函數中啡专,在這里,每個值的名稱都被轉換成一個字符串制圈,并且序數設置表示了此設置被創(chuàng)建的順序们童。
public enum Week{
MON, TUE, WED, THU, FRI, SAT, SUN;
}
// 內部調用了7次 Enum(String name, int ordinal):
new Enum<EnumTest>("MON",0);
new Enum<EnumTest>("TUE",1);
new Enum<EnumTest>("WED",2);
... ...
- 枚舉類是特殊的
class
,有構造器鲸鹦、方法和數據域慧库,被final
修飾,不可被繼承馋嗜; - 枚舉值
MON, TUE...
都是Week
類型的靜態(tài)常量(public static final 修飾
)齐板,故通常全部大寫。
// 獲取實例
Week w = Week.MON;
使用
一. 自定義方法、覆蓋枚舉的方法
自定義方法時必須在enum
實例序列最后添加分號甘磨。同時Java
要求必須先定義 enum
實例.
enum Week {
MON(2016, 12, 12), TUE(2016, 12, 13), WED(2016, 12, 14), THU(2016, 12, 15),
FRI(2016, 12, 16), SUN(2016, 12, 17), SUN(2016, 12, 18);
//自定義數據域 (get橡羞、set 封裝)
private int year;
private int mouth;
private int day;
// 構造枚舉值
private Week (int year, int mouth, int day){
this.year = year;
this.mouth = mouth;
this.day = day;
}
// 自定義方法
public String getDate(int day) {
for (Week w : Week.values()) { // 遍歷
if (w.getDay() == day) {
return toString();
}
}
return null;
}
//覆蓋方法
@Override
public String toString() {
return w.year + "年" + w.mouth + "月" + w.day + "日" ;
}
}
注意:
- 構造器只在構造枚舉值時被調用;
- 構造器只能私有
private
济舆,不允許public
修飾卿泽。保證了外部代碼無法構造新枚舉類的實例,因為枚舉值是public static final
的常量滋觉。 但枚舉類的方法和數據域允許外部訪問签夭。
// 錯誤寫法
Week week = new Week(2017, 1, 1);
// 正確寫法
Week week = Week.MON;
System.out.println(week.getDate());
二. switch 操作
public void change() {
Week week = Week.WED;
switch (week) {
case MON:
week = Week.MON;
break;
case TUE:
week = Week.TUE;
break;
case WED:
week = Week.WED;
break;
……
}
三. 實現接口
枚舉繼承java.lang.Enum
類。Java
不支持多繼承椎侠,所以枚舉對象不能繼承其它類第租。
public interface Behaviour {
void print();
String getDayOfMouth();
}
enum Week {
MON(2016, 12, 12), TUE(2016, 12, 13), WED(2016, 12, 14), THU(2016, 12, 15),
FRI(2016, 12, 16), SUN(2016, 12, 17), SUN(2016, 12, 18);
// 成員變量 (get、set 封裝)
private int year;
private int mouth;
private int day;
// 構造方法
private Week (int year, int mouth, int day){
this.year = year;
this.mouth = mouth;
this.day = day;
}
// 接口方法
@Override
public String getDayOfMouth(int day) {
return this.day;
}
// 接口方法
@Override
public String print() {
System.out.println(w.year + "年" + w.mouth + "月" + w.day + "日");
}
四. 接口組織枚舉
public interface Animal {
enum Water implements Animal {
SHARK, DOLPHIN, WHALE
}
enum Land implements Animal {
DOG, CAT, PIG, WOLF, TIGER
}
}
五. 方法
繼承于Enum
的方法肺蔚。
-
int compareTo(E o)
比較此枚舉與指定對象的順序(Enum
實現了java.lang.Comparable
接口)煌妈。返回兩個枚舉值的順序之差。枚舉必須屬于同一個枚舉類宣羊,否則拋出ClassCastException()
異常璧诵。
// MON, TUE, WED, THU, FRI, SUN, SUN
Week.MON.compareTo(Week.WED); // 結果 -2
Week.WED.compareTo(Week.MON); // 結果 2
-
final boolean equals(Object other)
比較兩個枚舉類對象的引用。 -
Class<E> getDeclaringClass()
返回與此枚舉常量的枚舉類型相對應的Class
對象仇冯。
Week week = Week.MON;
System.out.println(week.getDeclaringClass().getName());
// 輸出結果:com.enumtest.test.Week;
-
String name()
返回此枚舉常量的名稱之宿,在其枚舉聲明中對其進行聲明。 -
int ordinal()
返回枚舉常量在枚舉類中的次序(初始常量序數為 0)苛坚。
Week.MON.ordinal(); // 結果 0
Week.WED.ordinal(); // 結果 2
-
String toString()
返回枚舉常量的名稱比被。
Week w = Week.MON;
System.out.println(w);//返回結果: MON
-
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
返回帶指定名稱的指定枚舉類型的枚舉常量,與toString()
方法相對應泼舱。
Week.valueOf("MON"); // 結果 Week.MON
-
values()
靜態(tài)方法等缀,返回一個包含全部枚舉值的數組。
Week weeks = Week.values();
for(Week w:weeks){
System.out.print(w + ",");
}
//返回結果:MON, TUE, WED, THU, FRI, SUN, SUN
五. 枚舉集合
java.util.EnumSet
:保證集合中的元素不重復娇昙。
java.util.EnumMap
:key
是enum
類型尺迂,value
可以是任意類型。
// EnumSet的使用
EnumSet<Week> weekSet = EnumSet.allOf(Week.class);
for (Week w : weekSet) {
System.out.println(w);
}
// EnumMap的使用
EnumMap<Week, String> weekMap = new EnumMap(Week.class);
weekMap.put(Week.MON, "星期一");
weekMap.put(Week.TUE, "星期二");
// ... ...
for (Iterator<Entry<Week, String>> iter = weekMap.entrySet().iterator();
iter.hasNext();) {
Entry<Week, String> entry = iter.next();
System.out.println(entry.getKey().name() + ":" + entry.getValue());
}
原理
enum
的語法結構和 class
的不同冒掌,但編譯器編譯之后生成一個class
文件噪裕。經反編譯,可知該class
文件生成了一個繼承java.lang.Enum<E>
的類股毫。
public class com.dev.test.Week extends java.lang.Enum{
public static final com.dev.test.Week MON;
public static final com.dev.test.Week TUE;
public static final com.dev.test.Week WED;
public static final com.dev.test.Week THU;
public static final com.dev.test.Week FRI;
public static final com.dev.test.Week SAT;
public static final com.dev.test.Week SUN;
static {};
public int getValue();
public boolean isRest();
public static com.dev.test.Week[] values();
public static com.dev.test.Week valueOf(java.lang.String);
com.dev.test.Week(java.lang.String, int, int, com.dev.test.Week);
}