在Java的枚举中使用==可以吗?

可以在Java中使用==来枚举,还是需要使用.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
}

我的2美分:这是Sun公司发布的Enum.java代码,也是JDK的一部分:

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;
    }


}

是的,==很好 - 保证每个值都只有一个参考。

但是,编写轮回方法还有更好的方法:

public int round(RoundingMode roundingMode) {
  switch (roundingMode) {
    case HALF_UP:
       //do something
       break;
    case HALF_EVEN:
       //do something
       break;
    // etc
  }
}

更好的方法是将函数放入枚举本身,所以你可以调用roundingMode.round(someValue) 。 这到达Java枚举的核心 - 它们是面向对象的枚举,与其他地方的“命名值”不同。

编辑:规范不是很清楚,但第8.9节规定:

枚举类型的主体可能包含枚举常量。 一个枚举常量定义了枚举类型的一个实例。 一个枚举类型除了由枚举常量定义的枚举类型之外没有其他实例。


是的,就好像您为枚举中的每个值创建了单例实例:

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
  }
}

但是, enum构造为您提供了各种好处:

  • 每个实例的toString()打印代码中给出的名称。
  • (如另一篇文章中提到的那样),可以使用switch-case控制结构将枚举类型的变量与常量进行比较。
  • 枚举中的所有值都可以使用每个枚举类型的“生成” values来查询
  • 下面是关于身份比较的重要内容:枚举值在没有克隆的情况下可以继续序列化。
  • 序列化是一个大怪物。 如果我要使用上面的代码而不是枚举,下面是身份平等的行为方式:

    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
    

    您可以使用涉及writeReplacereadResolve的技术来解决此问题,而不使用枚举(请参阅http://java.sun.com/j2se/1.4.2/docs/api/java/io/Serializable.html)...

    我猜测的重点是 - Java不再允许你使用枚举值的身份来测试相等性; 这是一种鼓励的做法。

    链接地址: http://www.djcxy.com/p/16333.html

    上一篇: Is it OK to use == on enums in Java?

    下一篇: C# Ensure Valid Enum Values