15

オブジェクトの.equals(Object)javadocに記載されています:

これは対称的です: null 以外の参照値 x と y の場合、y.equals(x) が true を返す場合に限り、x.equals(y) は true を返す必要があります。

コード例のほぼすべての場所で、最初のテストの 1 つとして.equals(Object)使用するオーバーライドされたメソッドを目にします。instanceof

public class Person {
    private String name;
    private int age;

    public boolean equals(Object obj) {
        if (obj == null)
            return false;
        if (obj == this)
            return true;
        if (!(obj instanceof Person))
            return false;
        ...
    }

}

今持っclass SpecialPerson extends Personているequals

        if (!(obj instanceof SpecialPerson))
            return false;

.equals()が対称であることを保証するものではありません。たとえば、ここで説明されています: any-reason-to-prefer-getclass-over-instanceof-when-generating-equals

Person a = new Person(), b = new SpecialPerson();

a.equals(b);    //sometimes true, since b instanceof Person
b.equals(a);    //always false

たぶん、SpecialPerson のスーパーへの equals 直接呼び出しの先頭に追加する必要がありますか?

    public boolean equals(Object obj) {
        if( !obj instanceof SpecialPerson )
            return super.equals(obj);
        ... 
        /* more equality tests here */
    }
4

5 に答える 5

0

両方のオブジェクトが共通のクラスから派生し、そのコントラクトが異なる型の子孫が等しいかどうかをチェックする方法を指定している場合を除き、型はそれ自体を他の型のオブジェクト (サブタイプであっても) と等しいと見なすべきではありません。

たとえば、抽象クラスStringyThingは文字列をカプセル化し、文字列への変換や部分文字列の抽出などを行うメソッドを提供できますが、バッキング形式に要件を課すことはありません。StringyThingたとえば、の可能なサブタイプの 1 つは、 の配列を含み、StringyThingそれらすべての文字列の連結の値をカプセル化する場合があります。の 2 つのインスタンスはStringyThing、文字列への変換で同一の結果が得られる場合に等しいと定義されStringyThing、型が互いに何も知らなかった他の方法では区別できない 2 つのインスタンス間の比較は、それにフォールバックする必要がある場合がありますが、StringyThing派生型には、さまざまな最適化を行うコードを含めることができます。ケース。たとえば、一方が「文字の繰り返し」を表し、もう一方が「文字の繰り返し」をStringyThing表す場合MchN後者のタイプは最初のものを知っているので、文字の繰り返しStだけが含まれているかどうかをチェックできます。このようなチェックは、文字列が等しいかどうかを示します。そのうちの。M/Nch

于 2013-09-02T20:07:52.653 に答える