枚舉(Enum),是一個(gè)進(jìn)過排序的、被打包成一個(gè)單一實(shí)體的項(xiàng)列表。一個(gè)枚舉的示例可以使用枚舉項(xiàng)列表中任意單一項(xiàng)的值。枚舉在各個(gè)語言當(dāng)中都有著廣泛的應(yīng)用,通常用來表示諸如顏色、方式、類別、狀態(tài)等等數(shù)目有限。形式分散。表達(dá)極為明確的量。Java從JDK5開始引入了對(duì)枚舉的支持。
在枚舉出現(xiàn)之前,如果想要表示一組特定的離散值,往往使用一些常量。例如:
package org.seckill.entity;
/**
* Created by chen on 2018/2/28.
*/
public class SeckillStat {
public static final int SUCCESS = 1;//秒殺成功
public static final int END = 0;//秒殺結(jié)束
public static final int REPEAT_KILL = -1;//重復(fù)秒殺
private int state;
private String info;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
當(dāng)然,常量也不僅僅局限于int型,諸如char和String等也是不在少于。然而,無論使用什么樣的類型,這樣做都有很多的壞處。這些常量通常都是連續(xù)。有無窮多個(gè)值的量,而類似這種表示類別的量則是離散的,并且通常情況下只有有限個(gè)值。用連續(xù)的量去表示離散量,會(huì)產(chǎn)生很多問題。例如,針對(duì)上述的SeckillStat類,如果對(duì)SeckillStat對(duì)象的type屬性進(jìn)行賦值,一般會(huì)采用如下方法:
SeckillStat seckillStat = new SeckillStat();
seckillStat.setState(1);
seckillStat.setInfo("秒殺成功");
這樣多的缺點(diǎn)有:(1)代碼可讀性差,易用性低。由于setState()方法的參數(shù)是int類型的,在閱讀代碼的時(shí)候往往會(huì)讓讀者一頭霧水,根本不明白這個(gè)1到底是什么意思,代表的是什么類型。當(dāng)然,要保證可讀性,還有一個(gè)辦法:
SeckillStat seckillStat = new SeckillStat();
//seckillStat.setState(1);
seckillStat.setState(SeckillStat.SUCCESS);t
而這樣的話,新的問題有來了。這樣做,客服端必須對(duì)這些常量去簡(jiǎn)歷理解,才能了解如何去使用這個(gè)東西。說白了,在調(diào)用的時(shí)候,如果用戶不到SeckillStat類中去查看,還真不知道這個(gè)參數(shù)應(yīng)該怎么傳。怎么調(diào)。像是setState(1)這種用戶也是再所難免,因?yàn)樗耆戏ǎ皇敲總€(gè)人都能建立起常量名代替數(shù)值,從而增加程序的可讀性、降低耦合性的意識(shí)。(2)類型不安全。在用戶去調(diào)用的時(shí)候,必須保證類型一直,同時(shí)取值范圍也要正確。像是setState(-100)這樣的調(diào)用時(shí)合法的,但是它并不合理,今后為程序代用中中問題。也許你會(huì)說,加一個(gè)有效驗(yàn)證嘛,但是,這樣做得話,又會(huì)引出下面的(3)問題。(3)耦合度高、擴(kuò)展性差。例如,因?yàn)槟承┰颍枰薷腅ntity類中的常量的值,那么,所有用到這些常量的代碼也就都需要修改,還得仔仔細(xì)細(xì)的修改,萬一漏了一個(gè),那可不是開玩笑的。同時(shí),這樣做也不利于擴(kuò)展。例如,加入針對(duì)狀態(tài)做了一個(gè)有效性驗(yàn)證,如果狀態(tài)增加了或者有所變動(dòng),則有效性驗(yàn)證也需要做對(duì)應(yīng)的修改,不利于后期維護(hù)。
枚舉就是為了這樣的問題而誕生的。他們給出了將一個(gè)任一項(xiàng)同另一個(gè)項(xiàng)比較的能力,并且可以在一個(gè)已定義項(xiàng)列表中進(jìn)行迭代。枚舉是一個(gè)特定類型的類。所有枚舉都是java中的新類java.lang.Enum的隱式子類。此類不能手工進(jìn)行子類定義。一個(gè)簡(jiǎn)單的枚舉可以是這樣的:
public enum SeckillStatEnum{
SECCESS,END,FAID;
}
上面的SeckillStat類可以改寫成這樣的:
package org.seckill.enums;
/**
* Created by chen on 2017/12/1.
*/
public enum SeckillStatEnum {
SUCCESS(1,"秒殺成功"),
END(0,"秒殺結(jié)束"),
REPEAT_KILL(-1,"重復(fù)秒殺"),
INNER_ERROR(-2,"系統(tǒng)異常"),
DATE_REWRITE(-3,"數(shù)據(jù)篡改");
private int state;
private String info;
SeckillStatEnum(int state, String info) {
this.state = state;
this.info = info;
}
public int getState() {
return state;
}
public String getInfo() {
return info;
}
public static SeckillStatEnum stateOf(int index)
{
for (SeckillStatEnum state : values())
{
if (state.getState()==index)
{
return state;
}
}
return null;
}
}