4

我有一个 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);
}

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

有什么我遗漏的陷阱吗?我看不出有什么明显的错误...

4

2 回答 2

14

嗯,有两件事:

  • 你没有压倒一切——你超载了,而且以一种令人困惑的方式
  • 你的平等不是对称的 -MyEnum.A.equals("A")是真的,但是"A".equals(MyEnum.A)是假的。

我不会这样做——如果你对代码执行相等性检查,这样做很容易……但明确一点会更清楚。

毕竟,这只是以下之间的区别:

if (value.equals("A"))

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

我认为后者更清楚。

于 2013-03-15T13:52:01.793 回答
6

陷阱很简单:你没有覆盖equals(Object),而是引入了另一种方法equals(String)。该方法不会被任何基础设施调用equals对您的对象使用,因为动态分派仅适用于调用该方法的对象的运行时类型,并且所有方法参数的静态类型用于在编译时解析方法签名.

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

值得庆幸的是,枚举已经阻止您通过硬编码equalshashCode使其最终化来尝试此操作。

于 2013-03-15T13:51:43.650 回答