昨天在做besuper的小型交互游戲的時候,強默默走到我邊上吱涉,然后看了一眼我的代碼,又一如既往的開始噴我:你這寫的啥玩意兒巴饫铩怎爵!這么多類常量定義在前面,干嘛創(chuàng)建一個枚舉類型盅蝗!也就是因為這樣被噴的經(jīng)歷鳖链,讓我今天下決心好好了解一下enum的用法。
優(yōu)勢
為什么在有些時候我們要用枚舉呢墩莫?所以先看看枚舉常量和我們經(jīng)常使用的類常量芙委、實例常量比較,有什么優(yōu)勢狂秦。
- 枚舉常量更加簡單
在接口中定義類常量灌侣,如下:
interface Season {
int Spring = 0;
int Summer = 1;
int Autumn = 2;
int Winter = 3;
}
在枚舉中定義常量
public enum Season {
SPRING, SUMMER, AUTUMN, WINTER;
}
枚舉只需要定義每一個枚舉項(其實每個枚舉項就是一個枚舉類型的實例對象),不需要定義枚舉值裂问,而接口常量(即類常量)則必須初始化侧啼,否則編譯不通過。兩個引用方式相同(類名.屬性),但是枚舉表示的是一個枚舉項堪簿,字面量就是SPRING痊乾、SUMMER、AUTUMN椭更、WINTER哪审,而接口常量字面量是一個int類型:0、1虑瀑、2湿滓、3畏腕。
- 枚舉常量屬于穩(wěn)定型
如果我們使用一個接口常量,我們就必須要對輸入值進(jìn)行檢查茉稠,確定是否越界描馅,如果常量非常龐大,校驗輸入就是一件非常麻煩的事情而线,但是這個過程又無法避免铭污。
public void describe(int s) {
if (s >= 0 && s <= 4) {
switch(s) {
case Season.Summer:
System.out.println("Summer is very hot!");
break;
case Season.Winter:
System.out.println("Winter is very cold!");
break;
}
}
}
如果是枚舉常量,我們看看它是怎么避開校驗的膀篮。
public void describe(Season s) {
switch(s) {
case Season.Summer:
System.out.println("Summer is very hot!");
break;
case Season.Winter:
System.out.println("Winter is very cold!");
break;
}
}
因為我們已經(jīng)限定了輸入的參數(shù)只能是Season枚舉嘹狞,所以只能輸入Season的四個實例。這也是枚舉很好的一個作用:在編譯期間限定類型誓竿,不允許發(fā)生越界的情況磅网。
- 枚舉具有內(nèi)置方法
每個枚舉都是java.lang.Enum的子類。該基類提供了很多方法:獲得排序值得ordinal(),compareTo()等筷屡。比如列出所有的枚舉值:
public static void main(String[] args) {
for (Season s : Season.value()) {
System.out.println(s);
}
}
- 枚舉可以自定義方法
這一點看上去不是枚舉的優(yōu)點涧偷,因為在定義類常量所在的類里面也可以定義方法,但是枚舉在可以定義靜態(tài)方法和實例方法的基礎(chǔ)之上毙死,還可以從根本上杜絕枚舉常量在別的類中被實例化(因為枚舉的構(gòu)造方法默認(rèn)是private的燎潮,所以只允許在枚舉中實例化,不允許在別的地方進(jìn)行實例化扼倘。這也是枚舉的意義之一H贩狻)。
枚舉實現(xiàn):
enum Season {
SPRING, SUMMER, AUTUMN, WINTER;
public static Season getComfortableSeason() {
return SPRING;
}
}
類實現(xiàn):
class Season {
public final static int Spring = 0;
public final static int Summer = 1;
public final static int Autumn = 2;
public final static int Winter = 3;
public static void int getComfortableSeason() {
return Spring;
}
}
- 雖然枚舉在很多方面都比接口常量和類常量做得好再菊,但是有一點它比不上接口常量和類常量爪喘,就是繼承。因為枚舉是不能被繼承的纠拔,也就是說一個枚舉常量定義之后秉剑,除非修改重構(gòu),否則無法做擴展绿语。但是秃症,我們依舊要用枚舉常量替代接口常量或者類常量候址。
枚舉常量一個很關(guān)鍵的用法
先定義一個枚舉類
enum Season {
SPRING, SUMMER, AUTUMN, WINTER;
}
}
再定義一個類
public class chooseSeason {
String s = "spring";
Season season = Season.valueOf(s.toUpperCase());
switch (season) {
case SPRING :
System.out.println("這是春天");
case SUMMER:
System.out.println("這是夏天");
case AUTUMN:
System.out.println("這是秋天");
case WINTER:
System.out.println("這是冬天");
}
}
這里吕粹,我們是想把一個常量傳入switch,然后進(jìn)行一個選擇岗仑。這里我們運用了枚舉的第一個特點匹耕,就是switch()里面的參數(shù)類型定死為Season枚舉類型了。但是荠雕,如果我們得到的數(shù)據(jù)是一個字符串稳其,我們想把這個字符串的字面量當(dāng)做switch的條件傳入怎么辦呢驶赏?這個時候,我們把字符串變成大寫既鞠,并通過Enum里面的valueOf()方法煤傍,把字符串轉(zhuǎn)成枚舉常量。并且這個枚舉常量的字面量就是原來字符串的字面量嘱蛋。
這樣的轉(zhuǎn)換在switch里面真的好用