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

Pau*_*ams 4 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;
       }
   }
Run Code Online (Sandbox Code Playgroud)

我想添加自定义比较器:

public boolean equals(String code){
    return getCode().equals(code);
}
Run Code Online (Sandbox Code Playgroud)

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

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

Jon*_*eet 14

好吧,有两件事:

  • 你没有压倒一切 - 你正在超载,而且是一种令人困惑的方式
  • 你的平等不对称 - MyEnum.A.equals("A")是真的,但却"A".equals(MyEnum.A)是错误的.

我不会这样做 - 你在哪里用代码执行相等检查,这很容易做到......但是明确它是更清楚的.

毕竟,它只是区别:

if (value.equals("A"))
Run Code Online (Sandbox Code Playgroud)

if (value.getCode().equals("A"))
Run Code Online (Sandbox Code Playgroud)

我认为后者更清楚.


Mar*_*nik 6

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

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

值得庆幸的是,枚举已经阻止你硬编码在尝试此equalshashCode,使他们最终的决定.