問題
我知道Java枚舉會被編譯成一個包含私有構造參數和一堆靜態方法的類,當去比較兩個枚舉的時候,總是使用equals()方法,例如:
public useEnums(SomeEnum a) { if(a.equals(SomeEnum.SOME_ENUM_VALUE)) { ... } ... }
除此之外,我也可以使用 == 替代equals() 方法
public useEnums2(SomeEnum a) { if(a == SomeEnum.SOME_ENUM_VALUE) { ... } ... }
我有5年以上的java編程經驗,並且我想我也懂得 == 和 equals() 之間的區別,但是我仍然覺得很困惑,哪一個操作符才是我該使用的。
答案
二者皆對,如果你看過枚舉的源碼,你會發現在源碼中,equals也僅僅非常簡單的 == 。 我使用 == ,因為無論如何,這個左值是可以為 null的
譯者補充 java.lang.Enum 中Equals 代碼:
public final boolean equals(Object other) { return this==other; }
額外答案
能在枚舉中使用 == 進行判斷?
答案是肯定的,因為枚舉有着嚴格的實例化控制,所以你可以用 == 去做比較符,這個用法,在官方文檔中也有明確的說明。
JLS 8.9 Enums 一個枚舉類型除了定義的那些枚舉常量外沒有其他實例了。 試圖明確地說明一種枚舉類型是會導致編譯期異常。在枚舉中final clone方法確保枚舉常量從不會被克隆,而且序列化機制會確保從不會因為反序列化而創造復制的實例。枚舉類型的反射實例化也是被禁止的。總之,以上內容確保了除了定義的枚舉常量之外,沒有枚舉類型實例。
因為每個枚舉常量只有一個實例,所以如果在比較兩個參考值,至少有一個涉及到枚舉常量時,允許使用“==”代替equals()。(equals()方法在枚舉類中是一個final方法,在參數和返回結果時,很少調用父類的equals()方法,因此是一種恆等的比較。)
什么時候 == 和 equals 不一樣?
As a reminder, it needs to be said that generally, == is NOT a viable alternative to equals. When it is, however (such as with enum), there are two important differences to consider: 通常來說 == 不是一個 equals的一個備選方案,無論如何有2個重要的不同處需要考慮:
== 不會拋出 NullPointerException
enum Color { BLACK, WHITE }; Color nothing = null; if (nothing == Color.BLACK); // runs fine if (nothing.equals(Color.BLACK)); // throws NullPointerException
== 在編譯期檢測類型兼容性
enum Color { BLACK, WHITE }; enum Chiral { LEFT, RIGHT }; if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine if (Color.BLACK == Chiral.LEFT); // DOESN'T COMPILE!!! Incompatible types!
什么時候使用 == ?
Bloch specifically mentions that immutable classes that have proper control over their instances can guarantee to their clients that == is usable. enum is specifically mentioned to exemplify. 具體來說,那些提供恰當實例控制的不可變類能夠保證 == 是可用的,枚舉剛好符合這個條件。
考慮靜態工廠方法代替構造器 它使得不可變的類可以確保不會存在兩個相等的實例,即當且僅當a==b的時候才有a.equals(b)為true。如果類保證了這一點,它的客戶端可以使用“==”操作符來代替equals(Object)方法,這樣可以提升性能。枚舉類型保證了這一點
總而言之,在枚舉比較上使用 == , 因為: 1. 能正常工作 2. 更快 3. 運行時是安全的 4. 編譯期也是安全的
stackoverlfow鏈接:http://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals
參考鏈接:http://blog.csdn.net/x_iya/article/details/53291536