ava中的枚舉是在JDK1.5以后出現(xiàn)的。之前的開發(fā)過程中并沒有用過,但是有碰到過關(guān)于枚舉的代碼好唯。貌似是一種更為簡單有效的常量定義方式馍资。學習之筒主,希望以后的寫代碼過程中可以熟悉并掌握枚舉的用法。
使用場景:
每當需要一組固定的常量的時候,如一周的天數(shù)乌妙、一年四季等使兔。或者是在我們編譯前就知道其包含的所有值的集合藤韵,比如定義了一些狀態(tài)等等虐沥。這個時候就有可能需要使用枚舉了。
與 public static final 的常量定義方式進行比較:
在以上的場景中泽艘,回顧以往的做法欲险,比如我們定義這樣一些狀態(tài):
public class State {
public static final int Normal = 0;//正常
public static final int Update = 1;//已更新
public static final int Delete = 2;//已刪除
}
使用的時候,在程序中直接使用 類名.常量名 就可以了匹涮。但是這樣還存在一些問題天试。比如:
public void doSomething(int state){
switch(state){
case State.Normal:
...
break;
case State.Update:
...
break;
case State.Delete:
...
break;
default:
...
}
}
在程序運行過程中,傳入的state變量很有可能并不是我們期待的焕盟。比如 doSomething(4) 這樣的調(diào)用方式有可能出現(xiàn)問題秋秤,因為我們想要的參數(shù)值僅僅是Normal、Update脚翘、Delete中的一個灼卢。為此,我們不得不在default分支中做一些處理來應對這種情況来农。換句話說鞋真,這是類型不安全的。
另外沃于,在我們對程序進行調(diào)試的過程中涩咖,上面定義的常量會轉(zhuǎn)換成一些毫無意義的整數(shù)值,也就是所謂的魔術(shù)數(shù)字繁莹。給我們的調(diào)試帶來痛苦檩互。
因為整形枚舉屬于編譯期常量,所以編譯過程完成后咨演,所有客戶端和服務器端引用的地方闸昨,會直接將整數(shù)值寫入。這樣薄风,當你修改舊的枚舉整數(shù)值后或者增加新的枚舉值后饵较,所有引用地方代碼都需要重新編譯,否則運行時刻就會出現(xiàn)錯誤遭赂。
那如果換成枚舉常量呢循诉?
public enum State {
Normal,Update,Delete
}
類型安全檢查:
public void doSomething(State state){
switch(state){
case Normal:
...
break;
case Update:
...
break;
case Delete:
...
break;
default:
...
}
}
調(diào)用doSomething(State state)方法時,在編譯期間就會限定類型撇他,不允許越界的情況出現(xiàn)茄猫。
另外狈蚤,枚舉提供了一些內(nèi)置的方法,比如划纽,列出所有的枚舉值等炫惩。這些方法簡化了常量的使用。
枚舉類型的使用
- 常量:
public enum State{
Normal,Update,Delete
}
遍歷枚舉常量:
for(State state:State.values()){
System.out.println(state);
}
- 自定義屬性阿浓、方法:
public enum State{
//若之后為枚舉類型添加屬性或方法他嚷,最后一個枚舉常量后面記得加分號
Normal("正常",0),Update("已更新",1),Delete("已刪除",2);
private String name;
private int index;
// 構(gòu)造方法,注意:構(gòu)造方法不能為public芭毙,因為enum并不可以被實例化
private State(String name, int index) {
this.name = name;
this.index = index;
}
// get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (State c : State .values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
//覆蓋toString方法,這樣調(diào)試就不會看到魔術(shù)數(shù)字啦
@Override
public String toString(){
return name+":"+index;
}
}
public void test(){
for (State state : State.values()) {
//輸出:正常:0 已更新:1 已刪除:2
System.out.println(state);
}
}
實際上筋蓖,以上枚舉聲明定義的類型是一個final類,因此枚舉類型不可以被繼承退敦。所有的枚舉都繼承自java.lang.Enum類粘咖。
其中,Normal侈百、Update瓮下、Delete是這個枚舉類的三個實例,他們都是static final類型的對象钝域。Normal("正常",0),Update("已更新",1),Delete("已刪除",2)正是調(diào)用了State類的私有構(gòu)造函數(shù)State(String name, int index)進行實例化的讽坏。
因此,枚舉類型可以作為一個類來使用例证,其不能被繼承路呜。所以他比常量枚舉更加強大。
- 實現(xiàn)接口
public interface HandleState{
void printState();
}
public enum State implements HandleState{
//若之后為枚舉類型添加屬性或方法织咧,最后一個枚舉常量后面記得加分號
Normal("正常",0),Update("已更新",1),Delete("已刪除",2);
private String name;
private int index;
// 構(gòu)造方法胀葱,注意:構(gòu)造方法不能為public,因為enum并不可以被實例化
private State(String name, int index) {
this.name = name;
this.index = index;
}
// get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (State c : State .values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
//覆蓋toString方法,這樣調(diào)試就不會看到魔術(shù)數(shù)字啦
@Override
public String toString(){
return name+":"+index;
}
public void printState() {
System.out.println(this);
}
}
可以看到笙蒙,枚舉和一般的類一樣都可以實現(xiàn)接口抵屿。
- Enum 相關(guān)工具類
JDK5.0 中在增加 Enum 類的同時,也增加了兩個工具類 EnumSet 和 EnumMap捅位,這兩個類都放在 java.util 包中轧葛。具體的使用就查看官方文檔吧,這里不再贅述绿渣。