问题
在Java中使用==on枚举是否可以,或者我是否需要使用.equals()?在我的测试中,==总是有效,但我不确定我是否能保证这一点。特别是,枚举上没有.clone()方法,所以我不知道是否有可能获得枚举,其中.equals()将返回不同于==的值。
例如,这样就可以了:
public int round(RoundingMode roundingMode) {
if(roundingMode == RoundingMode.HALF_UP) {
//do something
} else if (roundingMode == RoundingMode.HALF_EVEN) {
//do something
}
//etc
}
或者我需要这样写它:
public int round(RoundingMode roundingMode) {
if(roundingMode.equals(RoundingMode.HALF_UP)) {
//do something
} else if (roundingMode.equals(RoundingMode.HALF_EVEN)) {
//do something
}
//etc
}
#1 热门回答(125 赞)
仅仅是我的2美分:这是由Sun发布的Enum.java的代码,也是JDK的一部分:
public abstract class Enum>
implements Comparable, 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;
}
}
#2 热门回答(73 赞)
是的,==很好 - 保证每个值只有一个参考。
但是,有一种更好的方法来编写圆形方法:
public int round(RoundingMode roundingMode) {
switch (roundingMode) {
case HALF_UP:
//do something
break;
case HALF_EVEN:
//do something
break;
// etc
}
}
这样做的更好的方法是将功能放在枚举本身中,所以你可以调用roundingMode.round(someValue)。这与Java enums的核心 - 他们是对象 - orientedenums,不像其他地方发现的"命名值"。
编辑:规格不是很清楚,但section 8.9陈述:
枚举类型的主体可能包含枚举常量。枚举常量定义枚举类型的实例。枚举类型没有除其枚举常量定义的实例之外的实例。
#3 热门回答(12 赞)
是的,就好像你为枚举中的每个值创建了单例实例:
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
}
}
但是,enumconstruct为你提供了各种好处:
每个实例的toString()打印代码中给出的名称。
(如另一篇文章中所述),可以使用switch-case控制结构将枚举类型的变量与常量进行比较。
可以使用为每个枚举类型"生成"的值字段查询枚举中的所有值
这是w.r.t身份比较中最重要的一个:枚举值在没有克隆的情况下在序列化中存活。
序列化是一个很大的问题。如果我使用上面的代码而不是枚举,这里是身份相等的行为方式:
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
我想重点是 - Java不遗余力地允许你使用枚举值的身份来测试相等性;这是一种鼓励的做法。