恕我直言,我懷疑你沒怎麼用過枚舉

恕我直言,我懷疑你沒怎麼用過枚舉

我們是否一樣?

估計很多小夥伴(也包括我自己)都有這種情況,在自學 Java語言看書時,關於枚舉 enum這一塊的知識點可能都有點 “輕敵” ,覺得這塊內容非常簡單,一帶而過,而且在實際寫代碼過程中也不注意運用。

是的,我也是這樣!直到有一天我提的代碼審核沒過,被技術總監一頓批,我才重新拿起了《Java編程思想》,把枚舉這塊的知識點重新又審視了一遍。

恕我直言,我懷疑你沒怎麼用過枚舉

為什麼需要枚舉

常量定義它不香嗎?為啥非得用枚舉?

舉個栗子,就以視頻網站上傳視頻為例,視頻一般有三個狀態:草稿審核發佈,我們可以將其定義為靜態常量

恕我直言,我懷疑你沒怎麼用過枚舉

對於這種單值類型的靜態常量定義,本身也沒錯,主要是在使用的地方沒有一個明確性的約束而已,比如:

恕我直言,我懷疑你沒怎麼用過枚舉

比如這裡的 judgeVideoStatus 函數的本意是傳入 VideoStatus 的三種靜態常量之一,但由於沒有類型上的約束,因此傳入任意一個

int值都是可以的,編譯器也不會提出任何警告。

但是在枚舉類型出現之後,上面這種情況就可以用枚舉嚴謹地去約束,比如用枚舉去定義視頻狀態就非常簡潔了:

恕我直言,我懷疑你沒怎麼用過枚舉

而且主要是在用枚舉的地方會有更強的類型約束

恕我直言,我懷疑你沒怎麼用過枚舉

這樣在使用 judgeVideoStatus 函數時,入參類型就會受到明確的類型約束,一旦傳入無效值,編譯器就會幫我們檢查,從而規避潛在問題。

除此之外,枚舉在擴展性方面比普常量更方便、也更優雅。

恕我直言,我懷疑你沒怎麼用過枚舉

重新系統認識一下枚舉

還是拿前文《答應我,別再if/else走天下了可以嗎》中的那個例子來說:比如,在後臺管理系統中,肯定有用戶角色一說,而且角色一般都是固定的,適合定義成一個枚舉:

恕我直言,我懷疑你沒怎麼用過枚舉

接下來我們就用這個 UserRole為例來說明枚舉的所有基本用法

恕我直言,我懷疑你沒怎麼用過枚舉

除此之外,枚舉還可以用於 switch語句中,而且意義更加明確:

恕我直言,我懷疑你沒怎麼用過枚舉

恕我直言,我懷疑你沒怎麼用過枚舉

自定義擴充枚舉

上面展示的枚舉例子非常簡單,僅僅是單值的情形,而實際項目中用枚舉往往是多值用法。

比如,我想擴充一下上面的 UserRole枚舉,在裡面加入 角色名 -- 角色編碼 的對應關係,這也是實際項目中常用的用法。

這時候我們可以在枚舉裡自定義各種屬性、構造函數、甚至各種方法:

恕我直言,我懷疑你沒怎麼用過枚舉

從上述代碼可知,在 enum枚舉類中完全可以像在普通 Class裡一樣聲明屬性、構造函數以及成員方法。

恕我直言,我懷疑你沒怎麼用過枚舉

枚舉 + 接口 = ?

比如在我的前文《答應我,別再if/else走天下了可以嗎》中講煩人的 if/else消除時,就講過如何通過

讓枚舉去實現接口來方便的完成。

這地方不妨再回顧一遍:

什麼角色能幹什麼事,這很明顯有一個對應關係,所以我們首先定義一個公用的接口 RoleOperation,表示不同角色所能做的操作:

恕我直言,我懷疑你沒怎麼用過枚舉

接下來我們將不同角色的情況全部交由枚舉類來做,定義一個枚舉類

RoleEnum,並讓它去實現 RoleOperation接口:

恕我直言,我懷疑你沒怎麼用過枚舉

這樣,在調用處就變得異常簡單了,一行代碼就行了,根本不需要什麼 if/else

恕我直言,我懷疑你沒怎麼用過枚舉

而且這樣一來,以後假如我想擴充條件,只需要去枚舉類中加代碼即可,而不用改任何老代碼,非常符合開閉原則

恕我直言,我懷疑你沒怎麼用過枚舉

枚舉與設計模式

什麼?枚舉還能實現設計模式?

是的!不僅能而且還能實現好幾種!

1、單例模式

恕我直言,我懷疑你沒怎麼用過枚舉

2、策略模式

這個也比較好舉例,比如用枚舉就可以寫出一個基於策略模式的加減乘除計算器

恕我直言,我懷疑你沒怎麼用過枚舉

恕我直言,我懷疑你沒怎麼用過枚舉

專門用於枚舉的集合類

我們平常一般習慣於使用諸如: HashMapHashSet等集合來盛放元素,而對於枚舉,有它專門的集合類: EnumSetEnumMap

1、EnumSet

EnumSet 是專門為盛放枚舉類型所設計的 Set 類型。

還是舉例來說,就以文中開頭定義的角色枚舉為例:

恕我直言,我懷疑你沒怎麼用過枚舉

比如系統裡來了一批人,我們需要查看他是不是某個角色中的一個:

恕我直言,我懷疑你沒怎麼用過枚舉

2、EnumMap

同樣, EnumMap 則是用來專門盛放枚舉類型為 keyMap 類型。

比如,系統裡來了一批人,我們需要統計不同的角色到底有多少人這種的話:

恕我直言,我懷疑你沒怎麼用過枚舉

EnumMap可以說非常方便了。

恕我直言,我懷疑你沒怎麼用過枚舉

總 結

小小的枚舉就玩出這麼多的花樣,不過好在探索和總結的過程還挺有意思的,也複習了很多知識,慢慢來吧。


分享到:


相關文章: