2013-03-15 25 views
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); 
} 

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

有没有我缺少的缺陷?我不能看到任何明显的错误...

+1

看起来很好 - 你为什么需要它?枚举是常量,因此使用普通比较来比较它们应该没问题。 – 2013-03-15 13:51:51

+0

有什么意义?除非你用相同的字符串初始化几个枚举... – assylias 2013-03-15 13:53:10

+0

那么,我与很多使用普通旧字符串的遗留代码接口,所以这将简化迁移,而遗留代码赶上... – PaulJWilliams 2013-03-15 13:54:44

回答

14

好吧,两件事情:

  • 你不重写 - 你超载,并在一个混乱的方式
  • 你平等是不是对称的 - MyEnum.A.equals("A")是真实的,但"A".equals(MyEnum.A)是假的。

我不会做它 - 在这里你与代码进行平等的检查,这是容易做到的...但它更清晰更明确一些吧。

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

if (value.equals("A")) 

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

而且我认为后者更清晰。

+1

或甚至'value.codeEquals(“A”)'如果你真的想要快捷方式。 – yshavit 2013-03-15 14:16:24

6

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

如果“纠正”这equals(Object),但保留的逻辑,那么你已经违反了合同equals,因为你不满足对称性:如果另一个字符串通过String.equals(yourObject)相比,你的话就会返回false和你不能影响这一点。这是使用Java的单派遣机制来定义等式关系的限制。

谢天谢地,枚举已经阻止你试图通过硬编码equalshashCode并使它们最终。