一、分析 常量的聲明是每一個項目中不可或缺的,在Java1.5之前,我們只有兩種方式的聲明:類常量和接口常量。不過,在1.5版之后有了改進,即新增了一種常量聲明方式,枚舉常量。代碼如下: enum Season{ Spring,Summer,Autumn,Winter; }
二、場景 那么枚舉常量與我們的經常使用的類常量和靜態常量比有什么優勢呢?
1.枚舉常量更簡單 先把Season枚舉翻譯成接口,代碼如下: interface Season{ int Sprint = 0; int Summer = 1; int Autumn = 2; int Winter = 3; }
枚舉只需要定義每個枚舉項,不需要定義枚舉值,而接口常量(或類常量)則必須定義值,否則編譯通不過;兩個引用的方式相同(都是“類名.屬性”,如Season.Sprint),但是枚舉表示的是一個枚舉項,字面含義是春天,而接口常量卻是 一個Int類型。
2.枚舉常量屬於穩態型 使用常量接口,我們得對輸入值進行檢查,確定是否越界,如果常量非常龐大,校驗輸入就是一件非常麻煩的事情,但這是一個不可逃避的過程。
接口常量
public interface ConstInterfaceA { public static final String CONST_A = "aa"; public static final String CONST_C = "ac"; }
存在問題:
1) 無法限制開發員繼承/實現接口.
2) 開發員能夠在子接口里繼續添加常量.而這些常量可能得不到祖先層的支持.
3) 常量作為參數時,是String,int等弱類型,開發員可以傳入沒有在常量接口里定義的值,這個問題無法通過編譯器發現.
4) 由於開發員可以直接寫常量值, 所以不能用==對比,只能用equals對比,不能優化性能
5) 開發員在沒有參考資料時,不可能知道某個int型的參數到底應該賦什么內容.
6) 編譯時,是直接把常量的值編譯到類的二進制代碼里,常量的值在升級中變化后,需要重新編譯所有引用常量的類,因為里面存的是舊值.
類常量
public class ConstClass { private static final String Success = "成功"; private static final String Fail = "失敗"; }
1、JDK編譯時,直接把常量編譯到使用的地方。在修改變量值后,其它類有可能會出現編譯到舊常量值的問題。
2、只能用equals比較,性能較低。無法保證類型是否合法,限定類型值。
3、如果使用了private,限定了只能當前類的擁有者才可以修改,如果使用public,則子類可以繼承修改,父類並不知情
枚舉常量
public enum Day { YICODE(1), ERCODE(2), YIMESSAGE("星期一"), ERMESSAGE("星期二"), XINGQI_YI(001,"星期一"), XINGQI_ER(002,"星期二"), XINGQI_SAN(003,"星期三"), XINGQI_SI(004,"星期四"), XINGQI_WU(005,"星期五"), XINGQI_LIU(006,"星期六"), XINGQI_RI(007,"星期日"); private int code; private String massage; Day(int code, String message){ this.code=code; this.massage=message; } Day(int code){ this.code=code; } Day(String message){ this.massage=message; } public int getCode() { return code; } public String getMassage() { return massage; } }
1、類型限定,性能較高,推薦使用。
2、枚舉構造方法是私有的,無法繼承修改,默認私有化無參構造方法,可用於枚舉單例
常量和枚舉區別
注意:很自然,枚舉會更加的簡潔明了. 而且枚舉支持 == 比較 switch case 等操作. 而且可以自己封裝方法. 所以個人認為枚舉確實好一些.
為什么枚舉支持 == 比較,而常量不支持吶?
因為final的變量地址值是不可變的。