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

さて、2つのこと:

  • あなたはオーバーライドしていません-あなたは過負荷であり、混乱している方法で
  • あなたの平等は対称的ではありません-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 のシングル ディスパッチ メカニズムを使用して等価関係を定義する際の制限です。

ありがたいことに、列挙型は、ハードコーディングして最終的なものにすることequalsで、これを試みることをすでに防いでいます。hashCode

于 2013-03-15T13:51:43.650 に答える