一.前言
在我們日常的開發過程中,我們經常定義使用常量;在Effective Java建議用枚舉來替換常量的使用,提高我們代碼的質量,總結一下枚舉定義常量的基本使用
二.枚舉類型說明
1.枚舉是一種數據類型,在jdk1.6版本才開始引入;
2.枚舉類型:在實際問題中,有些變量的取值被限定在一個有限的范圍內;
3.枚舉定義了一組業務類型相同的成員且成員的語義清晰;
三.常量與枚舉類型對比說明
常量存在問題:
1) 無法限制開發員繼承/實現接口.
2) 開發員能夠在子接口里繼續添加常量.而這些常量可能得不到祖先層的支持.
3) 常量作為參數時,是String,int等弱類型,開發員可以傳入沒有在常量接口里定義的值,這個問題無法通過編譯器發現.
4) 由於開發員可以直接寫常量值, 所以不能用==對比,只能用equals對比,不能優化性能
5) 開發員在沒有參考資料時,不可能知道某個int型的參數到底應該賦什么內容.
6) 編譯時,是直接把常量的值編譯到類的二進制代碼里,常量的值在升級中變化后,需要重新編譯所有引用常量的類,因為里面存的是舊值.
枚舉解決了以上所有問題,主要體現在:
1) 私有構造函數,避免被繼承和擴展.
2) 定義方法的參數時,必須用枚舉常量類類型,如上面的EnumClassA類型,這樣就轉變成了強類型,不會出現弱類型引起的問題.
3) 常量值地址唯一,可以用==直接對比,性能會有提高.
4) 開發員可以根據該參數類型打開對應的類,從而找到定義的常量.
5) 編譯時,沒有把常量值編譯到代碼里,即使常量的值發生變化也不會影響引用常量的類.
四.枚舉定義常量例子
public enum Color { /** * 紅色 */ RED("1"), /** * 黑色 */ BANK("2"), /** * 白色 */ WHITH("3"); private String value; private Color(String value) { this.value = value; } public String getValue() { return value; } }
說明:這個小例子定義了幾種顏色,紅色、黑色、白色分別用1、2、3來表示。在我們的開發使用中就可以用equest調用枚舉來進行判斷比較操作,提高了復用性,方便修改以及管理提高代碼的質量。
枚舉常量屬於穩態型
使用常量接口,我們得對輸入值進行檢查,確定是否越界,如果常量非常龐大,校驗輸入就是一件非常麻煩的事情,但這是一個不可逃避的過程。
public void describe(int s){ //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; …... } }
不用校驗,已經限定了是Season枚舉,所以只能是Season類的四個實例。這也是我們看重枚舉的地方:在編譯期間限定類型,不允許發生越界的情況。
五.總結
雖然枚舉在很多方面都比接口常量和類常量好用,但是它有一點比不上接口常量和類常量的,就是繼承,枚舉類型是不能有繼承的,也就是說一個枚舉常量定義完畢后,除非修改重構,否則無法做擴展。
六、建議
在 項目開發中,推薦使用枚舉常量代替接口常量或類常量。