|
| 1 | +## 比较java枚举成员使用equal还是== |
| 2 | + |
| 3 | +### 问题 |
| 4 | +我知道Java枚举会被编译成私有构造参数和一堆静态方法的一个类,当去比较两个枚举的时候,总是使用equals()方法,例如: |
| 5 | +```java |
| 6 | +public useEnums(SomeEnum a) |
| 7 | +{ |
| 8 | + if(a.equals(SomeEnum.SOME_ENUM_VALUE)) |
| 9 | + { |
| 10 | + ... |
| 11 | + } |
| 12 | + ... |
| 13 | +} |
| 14 | +``` |
| 15 | +除此之外,我也可以使用 == 替代equals() 方法 |
| 16 | +```java |
| 17 | +public useEnums2(SomeEnum a) |
| 18 | +{ |
| 19 | + if(a == SomeEnum.SOME_ENUM_VALUE) |
| 20 | + { |
| 21 | + ... |
| 22 | + } |
| 23 | + ... |
| 24 | +} |
| 25 | +``` |
| 26 | +我已经Java编程5年以上了,并且我想我也懂得 == 和 equals() 之间的区别,但是我仍然觉得困扰在这个问题上,哪一个操作符才是我该使用的。 |
| 27 | + |
| 28 | +### 答案 |
| 29 | + |
| 30 | +二者皆对,如果你看过枚举的源码,你会发现在源码中,equals也仅仅非常简单的 == 。 |
| 31 | +我使用 == ,无论如何,这个左值是可以为 null的 |
| 32 | + |
| 33 | + |
| 34 | +译者补充 java.lang.Enum 中Equals 代码: |
| 35 | +```java |
| 36 | +public final boolean equals(Object other) { |
| 37 | + return this==other; |
| 38 | +} |
| 39 | +``` |
| 40 | + |
| 41 | + |
| 42 | +### 额外答案 |
| 43 | +#### 能使用 == 在枚举判断中? |
| 44 | +答案是肯定的,因为枚举有着严格的实例化控制,所以你可以用 == 去比较实力,这在语言标准内也是有保证的。 |
| 45 | + |
| 46 | +>JLS 8.9 Enums |
| 47 | +>An enum type has no instances other than those defined by its enum constants. |
| 48 | +>It is a compile-time error to attempt to explicitly instantiate an enum type. The final clone method in Enum >ensures that enum constants can never be cloned, and the special treatment by the serialization mechanism ensures >that duplicate instances are never created as a result of deserialization. Reflective instantiation of enum types >is prohibited. Together, these four things ensure that no instances of an enum type exist beyond those defined by >the enum constants. |
| 49 | +>Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the >equals method when comparing two object references if it is known that at least one of them refers to an enum ?>constant. (The equals method in Enum is a final method that merely invokes super.equals on its argument and ?>returns the result, thus performing an identity comparison.) |
| 50 | +
|
| 51 | +#### 什么时候 == 和 equals 不一样? |
| 52 | +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: |
| 53 | +通常来说 == 不是一个 equals的一个备选方案,无论如何有2个重要的不同处需要考虑: |
| 54 | + |
| 55 | +##### == 不会抛出 NullPointerException |
| 56 | +```java |
| 57 | +enum Color { BLACK, WHITE }; |
| 58 | + |
| 59 | +Color nothing = null; |
| 60 | +if (nothing == Color.BLACK); // runs fine |
| 61 | +if (nothing.equals(Color.BLACK)); // throws NullPointerException |
| 62 | +``` |
| 63 | +##### == 在编译期检测类型兼容性 |
| 64 | +```java |
| 65 | +enum Color { BLACK, WHITE }; |
| 66 | +enum Chiral { LEFT, RIGHT }; |
| 67 | + |
| 68 | +if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine |
| 69 | +if (Color.BLACK == Chiral.LEFT); // DOESN'T COMPILE!!! Incompatible types! |
| 70 | +``` |
| 71 | + |
| 72 | +#### 什么时候使用 == ? |
| 73 | +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. |
| 74 | +具体来说,那些提供恰当实例控制的不可变类能够保证 == 是可用的,枚举刚好符合这个条件。 |
| 75 | + |
| 76 | +> Item 1: Consider static factory methods instead of constructors |
| 77 | +[...] it allows an immutable class to make the guarantee that no two equal instances exist: a.equals(b) if and only if a==b. If a class makes this guarantee, then its clients can use the == operator instead of the equals(Object) method, which may result in improved performance. Enum types provide this guarantee. |
| 78 | + |
| 79 | +总而言之,在枚举比较上使用 == , 因为: |
| 80 | +1. 能正常工作 |
| 81 | +2. 更快 |
| 82 | +3. 运行时是安全的 |
| 83 | +4. 编译期也是安全的 |
0 commit comments