Javaのequals()メソッドをオーバーライドしてもうまくいかない?質問する

Javaのequals()メソッドをオーバーライドしてもうまくいかない?質問する

今日、メソッドに関して興味深い (そして非常にイライラする) 問題に遭遇しました。equals()その問題により、十分にテストされたと思っていたクラスがクラッシュし、追跡に非常に長い時間がかかったバグが発生しました。

完全を期すために、私は IDE やデバッガーは使用せず、昔ながらのテキスト エディターと System.out だけを使用しました。時間は非常に限られており、学校のプロジェクトでした。

とにかく -

私は基本的なショッピングカートを開発していました。ArrayListBookオブジェクトのカートのaddBook()、、removeBook()メソッドを実装するために、がすでに に存在するかどうかを確認したいと思いました。それでは始めましょう -hasBook()BookCart

public boolean equals(Book b) {
    ... // More code here - null checks
    if (b.getID() == this.getID()) return true;
    else return false;
}

テストではすべて正常に動作します。6つのオブジェクトを作成し、データを入力します。多くの追加、削除、has()操作を実行するとCart、すべて正常に動作します。持っているequals(TYPE var)か、equals(Object o) { (CAST) var }しかし、動作しているので、それほど問題ではないと考えました。

Bookそこで問題に遭遇しました。のみBook クラス内から入力さIDれます。他のデータは入力されません。基本的には次のようになります。

public boolean hasBook(int i) {
    Book b = new Book(i);
    return hasBook(b);
}

public boolean hasBook(Book b) {
    // .. more code here
    return this.books.contains(b);
}

突然、equals(Book b)メソッドが機能しなくなりました。クラスが適切にテストされ、正しいと仮定して、優れたデバッガーなしでこれを追跡するのに非常に長い時間がかかりました。メソッドを次のようにCart交換した後:equals()

public boolean equals(Object o) {
    Book b = (Book) o;
    ... // The rest goes here   
}

すべてが再び機能し始めました。メソッドがBookパラメータを取らないことにしたのは、明らかにだったオブジェクトですかBook? 唯一の違いは、同じクラス内からインスタンス化され、1 つのデータ メンバーのみで満たされているようです。非常に混乱しています。教えてください。

ベストアンサー1

Java では、equals()継承されるメソッドは次のとおりObjectです。

public boolean equals(Object other);

つまり、パラメータは 型でなければなりませんObject。これは上書きする; メソッドpublic boolean equals(Book other)は、過負荷方法にequals()

ArrayListオーバーライドされたメソッドを使用してequals()コンテンツを比較します(例:メソッドcontains()equals()メソッド)。ないオーバーロードされたもの。ほとんどのコードでは、Objectの equals を適切にオーバーライドしていないものを呼び出すことは問題ありませんが、 とは互換性がありませんArrayList

したがって、メソッドを正しくオーバーライドしないと問題が発生する可能性があります。

毎回次のようにオーバーライドします。

@Override
public boolean equals(Object other){
    if (other == null) return false;
    if (other == this) return true;
    if (!(other instanceof MyClass)) return false;
    MyClass otherMyClass = (MyClass)other;
    ...test other properties here...
}

注釈を使用すると、@Override些細な間違いを修正するのに大いに役立ちます。

スーパークラスまたはインターフェースのメソッドをオーバーライドしていると思われる場合は、いつでもこれを使用してください。そうすれば、間違った方法でオーバーライドした場合にコンパイル エラーが発生します。

おすすめ記事