Is it OK to use == on enums in Java?
在Java中使用EnOCX1 0Ω可以吗?或者我需要使用EDCOX1?1?在我的测试中,
例如,是否可以:
1 2 3 4 5 6 7 8 | public int round(RoundingMode roundingMode) { if(roundingMode == RoundingMode.HALF_UP) { //do something } else if (roundingMode == RoundingMode.HALF_EVEN) { //do something } //etc } |
或者我需要这样写:
1 2 3 4 5 6 7 8 | public int round(RoundingMode roundingMode) { if(roundingMode.equals(RoundingMode.HALF_UP)) { //do something } else if (roundingMode.equals(RoundingMode.HALF_EVEN)) { //do something } //etc } |
就我2分:这是Sun发布的Enum.java代码,也是JDK的一部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { // [...] /** * Returns true if the specified object is equal to this * enum constant. * * @param other the object to be compared for equality with this object. * @return true if the specified object is equal to this * enum constant. */ public final boolean equals(Object other) { return this==other; } } |
是的,==很好-保证每个值只有一个引用。
但是,有一种更好的方法可以编写您的圆形方法:
1 2 3 4 5 6 7 8 9 10 11 | public int round(RoundingMode roundingMode) { switch (roundingMode) { case HALF_UP: //do something break; case HALF_EVEN: //do something break; // etc } } |
更好的方法是将功能放在枚举本身中,这样您就可以调用
编辑:规格不是很清楚,但第8.9节规定:
The body of an enum type may contain
enum constants. An enum constant
defines an instance of the enum type.
An enum type has no instances other
than those defined by its enum
constants.
是的,就好像您已经为枚举中的每个值创建了单例实例:
1 2 3 4 5 6 7 8 | public abstract class RoundingMode { public static final RoundingMode HALF_UP = new RoundingMode(); public static final RoundingMode HALF_EVEN = new RoundingMode(); private RoundingMode() { // private scope prevents any subtypes outside of this class } } |
但是,
- 每个实例的toString()打印代码中给定的名称。
- (如另一篇文章所述)可以使用
switch-case 控制结构将枚举类型的变量与常量进行比较。 - 可以使用为每个枚举类型"生成"的
values 字段查询枚举中的所有值。 - 下面是一个重要的W.R.T身份比较:枚举值可以在不进行克隆的情况下进行序列化。
系列化是一个很大的哥特式风格。如果我使用上面的代码而不是枚举,那么身份平等将如何表现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | RoundingMode original = RoundingMode.HALF_UP; assert (RoundingMode.HALF_UP == original); // passes ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(original); oos.flush(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); RoundingMode deserialized = (RoundingMode) ois.readObject(); assert (RoundingMode.HALF_UP == deserialized); // fails assert (RoundingMode.HALF_EVEN == deserialized); // fails |
您可以使用EDCOX1 4和EDCOX1 5的技术来解决这个问题,不需要枚举,(参见http://java.
我想关键是——Java不允许你使用EnUM值的身份来测试相等性,这是一种鼓励的做法。
==比较两个对象的引用。对于枚举,可以保证只有一个实例,因此对于任何两个相同的枚举,==都是真的。
参考文献:
http://www.ajaxonomy.com/2007/java/making-the-most-of-java-50-enum-tricks
(在Sun文档中找不到任何内容)
这里有一些你可能会觉得有趣的邪恶代码。D
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public enum YesNo {YES, NO} public static void main(String... args) throws Exception { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); Unsafe unsafe = (Unsafe) field.get(null); YesNo yesNo = (YesNo) unsafe.allocateInstance(YesNo.class); Field name = Enum.class.getDeclaredField("name"); name.setAccessible(true); name.set(yesNo,"YES"); Field ordinal = Enum.class.getDeclaredField("ordinal"); ordinal.setAccessible(true); ordinal.set(yesNo, 0); System.out.println("yesNo" + yesNo); System.out.println("YesNo.YES.name().equals(yesNo.name())"+YesNo.YES.name().equals(yesNo.name())); System.out.println("YesNo.YES.ordinal() == yesNo.ordinal()"+(YesNo.YES.ordinal() == yesNo.ordinal())); System.out.println("YesNo.YES.equals(yesNo)"+YesNo.YES.equals(yesNo)); System.out.println("YesNo.YES == yesNo" + (YesNo.YES == yesNo)); } |
枚举是阻塞多态代码的好地方。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | enum Rounding { ROUND_UP { public int round(double n) { ...; } }, ROUND_DOWN { public int round(double n) { ...; } }; public abstract int round(double n); } int foo(Rounding roundMethod) { return roundMethod.round(someCalculation()); } int bar() { return foo(Rounding.ROUND_UP); } |
==一般都可以,而且对==和
比较JavaEnm成员:= =或均衡器()?
请注意,通过rmi/iiop传输枚举时出现问题。查看此线程:
http://www.velocityreviews.com/forums/t390342-enum-equality.html