Java列舉最全解讀,這些好處你想象不到

1、列舉的意義

我們在很多時候會拿列舉和常量來做對比,可實際我們在程式中大量使用列舉的地方就是為了代替常量。因為相對於靜態的常量,列舉類顯得更加直觀,型別也相對更加安全。

1。1安全性

若一個方法中要求傳入方向這個引數,用常量的話,形參就是int型別,開發者傳入任意型別的int型別值就行,但是如果是列舉型別的話,就只能傳入列舉類中包含的物件。

1。2名稱空間

開發者要在命名的時候以SEASON_開頭,這樣另外一個開發者再看這段程式碼的時候,才知道這四個常量分別代表方位。

2、列舉的應用

列舉是JDK1。5新增的一個特性,它使用關鍵字

enum

來定義。列舉具有以下幾個特點:

2。1特點:

enum和class、interface的地位一樣

使用enum定義的列舉類預設繼承了java。lang。Enum,而不是繼承Object類,並且列舉類可以實現一個或多個介面。

列舉類的所有例項都必須放在第一行展示,不需使用new 關鍵字,不需顯式呼叫構造器。自動新增public static final修飾。

使用enum定義、非抽象的列舉類預設使用final修飾,不可以被繼承。

列舉類的構造器只能是私有的。

2。2使用:

前面我們說了列舉通常當引數使用,Java5新增了enum關鍵字,同時擴充套件了switch,在switch。。。case結構中的case表示式中直接寫入列舉值,且不需加入列舉類作為限定。

Java列舉最全解讀,這些好處你想象不到

3、列舉的特殊玩法

那除了代替常量,列舉還有什麼特殊的玩法呢?當然有啦,比如以下:

3。1 單例模式

單例模式可以說是每個java開發者必須掌握的一個設計模式了,通常我們說它的實現,有飽含式和餓漢式,也有經常說的雙重判斷,今天我們介紹另外一種方式,藉助列舉來實現:

public enum SingleEnum { INSTANCE; public void print(String word) { System。out。println(word); }}@Testpublic void testSingle() { SingleEnum。INSTANCE。print(“hello world”);}複製程式碼

如上,用列舉實現單例模式真的非常簡單,將類宣告為列舉,內部只定義一個值即可。這樣做主要是基於列舉的三個特性,即:

列舉類不能new,因此保證單例、列舉類不能被繼承、類不載入時,不會例項化

使用列舉類建立的單例還有一個好處,就是使用了反射也無法打破它的單例性質,這是相比較於其他的實現方式的一個優點。但是在實際的專案中這種寫法並不常見,這是因為我們習慣了將列舉作為常量來使用,很少在舉類中,新增複雜的業務邏輯。

3。2 策略模式

除了輕鬆實現上面的單例模式之外,列舉還可以非常簡單的實現策略模式,比如下面這個例子:

我現有一個介面,透過接受的引數,來決定最終的資料存在什麼地方,如果按照正常的寫法,可能就是很多的if/else

public void save(String type, Object data) { if (“db”。equals(type) { // 儲存到db saveInDb(data); } else if (“file”。equals(type)) // 儲存在檔案 saveInFile(data); } else if (“oss”。eqauls(type)) { // 儲存在oss saveInOss(type); }}複製程式碼

以上寫法雖說簡單直觀,但是當type型別多了之後,這個if/else的程式碼行數就會越來越多了,而且看起來也不美觀。如果我們換成列舉,基於策略模式的思想來解決上面的if/else問題,就會好得多。

public enum SaveStrategyEnum { DB(“db”) { @Override public void save(Object obj) { System。out。println(“save in db:” + obj); } }, FILE(“file”) { @Override public void save(Object obj) { System。out。println(“save in file: ” + obj); } }, OSS(“oss”) { @Override public void save(Object obj) { System。out。println(“save in oss: ” + obj); } }; private String type; SaveStrategyEnum(String type) { this。type = type; } public abstract void save(Object obj); public static SaveStrategyEnum typeOf(String type) { for (SaveStrategyEnum strategyEnum: values()) { if (strategyEnum。type。equalsIgnoreCase(type)) { return strategyEnum; } } return null; }}public void save(String type, Object data) { SaveStrategyEnum strategyEnum = SaveStrategyEnum。typeOf(type); if (strategyEnum != null) { strategyEnum。save(data); }}複製程式碼

以上主要利用的是抽象類 + 列舉來完成不同的策略具體實現,這種實現方式,相比較與前面的單例模式,還是更常見一點,雖然整體看下來沒有什麼難度,但是仔細看一看,會有兩個發現:

抽象方法的使用 (在模板設計模式中,更能體會抽象方法的使用妙處),利用列舉原生提供的values(),來實現遍歷,找到目標

以上就是我對列舉的的理解,在實際使用中還有很多想不到的好處,使用起來真的非常靈活方便!歡迎大家一起留言探討~

作者:程式設計師帥胡

連結:https://juejin。cn/post/6997800379907833892

著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。