在枚举中重载equals方法 - 任何陷阱?

时间:2013-03-15 13:50:08

标签: java enums

我有一个Java枚举,表示给定字段的潜在值,以及用于标识该值的唯一标识符:

    public enum MyEnum {
       TYPEA("A"),
       TYPEB("B")

       private String code;

       private MyEnum(String code){
          this.code = code;
       }

       public String getCode(){
          return code;
       }
   }

我想添加一个自定义比较器:

public boolean equals(String code){
    return getCode().equals(code);
}

这将允许我将我的枚举与字符串进行比较。

我有遗失的缺陷吗?我看不出任何明显的错误......

2 个答案:

答案 0 :(得分:14)

嗯,有两件事:

  • 你没有压倒 - 你正在超载,并且以一种令人困惑的方式
  • 您的平等不对称 - MyEnum.A.equals("A")为真,但"A".equals(MyEnum.A)为假。

我不会这样做 - 你希望用代码执行相等检查,这很容易做到......但是明确它是明确的。

毕竟,这只是:

之间的区别
if (value.equals("A"))

if (value.getCode().equals("A"))

我认为后者更清楚。

答案 1 :(得分:6)

陷阱很简单:你没有覆盖equals(Object),你引入了另一种方法equals(String)equals的任何基础结构调用都不会对您的对象使用该方法,因为动态调度仅适用于调用该方法的对象的运行时类型以及所有 static 类型的运行时类型方法参数用于在编译时解析方法签名。

如果您将此“更正”为equals(Object),但保留逻辑,那么您违反了equals合同,因为您不满足对称属性:如果将另一个字符串与您的对象进行比较通过String.equals(yourObject)它将返回false,你不能影响它。这是使用Java的单调度机制来定义等式关系的限制。

值得庆幸的是,枚举功能已经阻止您通过对equalshashCode进行硬编码并使其成为最终版本来尝试此操作。