我知道Java枚舉被編譯爲具備私有構造函數和一堆公共靜態成員的類。 比較給定枚舉的兩個成員時,我老是使用.equals()
,例如 程序員
public useEnums(SomeEnum a) { if(a.equals(SomeEnum.SOME_ENUM_VALUE)) { ... } ... }
可是,我遇到了一些使用equals運算符==
而不是.equals()的代碼: 編程
public useEnums2(SomeEnum a) { if(a == SomeEnum.SOME_ENUM_VALUE) { ... } ... }
我應該使用哪一個運算符? 安全
正如其餘人所說, ==
和.equals()
在大多數狀況下都有效。 您沒有比較其餘人指出的徹底不一樣類型的對象的編譯時間肯定性是有效和有益的,可是比較兩種不一樣編譯時間類型的對象的特殊類型的錯誤也能夠經過FindBugs找到(而且可能經過Eclipse / IntelliJ編譯時間檢查),所以Java編譯器發現它並無增長太多額外的安全性。 函數
然而: 性能
==
不會拋出NPE在我心目中是一個缺點 ==
。 幾乎不須要enum
類型爲null
,由於您可能但願經過null
表示的任何額外狀態均可以做爲附加實例添加到enum
中。 若是它意外地爲null
,那麼我寧願擁有一個NPE而不是==
默默地評估爲false。 所以,我不一樣意它在運行時的觀點是更安全的 。 最好養成永遠不要讓enum
值爲@Nullable
的習慣。 ==
更快的說法也是假的。 在大多數狀況下,您將在編譯時類型爲enum類的變量上調用.equals()
,在這些狀況下,編譯器能夠知道這與==
相同(由於enum
的equals()
方法能夠(不會被覆蓋)並能夠優化函數調用。 我不肯定編譯器當前是否這樣作,可是若是沒有這樣作,結果證實這是Java總體的性能問題,那麼我寧願修復該編譯器,也不肯讓100,000個Java程序員更改其編程樣式以適應特定編譯器版本的性能特徵。 enums
是對象。 對於全部其餘對象類型,標準比較是.equals()
,而不是==
。 我認爲對enums
進行例外處理是危險的,由於您可能最終會意外地將Object與==
而不是equals()
進行比較,尤爲是當您將enum
重構爲非枚舉類時。 在這種重構的狀況下,從上面的工做原理是錯誤的。 爲了使本身確信==
的使用是正確的,您須要檢查所討論的值是enum
仍是基元。 若是它是一個非enum
類,那將是錯誤的,可是很容易遺漏,由於代碼仍然能夠編譯。 使用.equals()
錯誤的惟一狀況是所討論的值是不是基元; 在這種狀況下,代碼將沒法編譯,所以更容易遺漏。 所以, .equals()
更容易被識別爲正確的,而且對於未來的重構更安全。 我實際上認爲Java語言應該在Objects上定義==,以在左側值上調用.equals(),併爲對象標識引入一個單獨的運算符,但這不是Java的定義方式。 優化
總之,我仍然認爲參數支持對enum
類型使用.equals()
。 spa
若是枚舉是正確的,那麼正確! .net
二者在技術上都是正確的。 若是您查看.equals()
的源代碼,則它僅.equals()
==
。 code
我使用==
,可是這將是null安全的。 對象
使用==
比較兩個枚舉值是可行的,由於每一個枚舉常量只有一個對象。
附帶說明一下,若是您像這樣編寫equals()
,則實際上無需使用==
來編寫空安全代碼:
public useEnums(final SomeEnum a) { if (SomeEnum.SOME_ENUM_VALUE.equals(a)) { … } … }
這是被稱爲「 從左邊比較常量」的最佳實踐,您絕對應該遵循。
我想補充多基因潤滑劑的答案:
我我的更喜歡equals()。 可是它對類型兼容性進行檢查。 我認爲這是一個重要的限制。
要在編譯時檢查類型兼容性,請在枚舉中聲明並使用自定義函數。
public boolean isEquals(enumVariable) // compare constant from left public static boolean areEqual(enumVariable, enumVariable2) // compare two variable
這樣,您將得到兩種解決方案的所有優點:NPE保護,易於閱讀的代碼以及在編譯時進行類型兼容性檢查。
我還建議爲枚舉添加一個UNDEFINED值。