Effective Java 第 2 版:第 3 章 項目 8
本項から、第 3 章「すべてのオブジェクトに共通のメソッド」に入る。
Object クラスのメソッドには、一般契約と呼ばれる使用上の決まりが存在する。
この契約を守って Object クラスのメソッドをオーバーライドしないと、契約を元に設計されている別のクラス HashMap などにおいて、Object クラスのメソッドをオーバーライドしたクラスを適切に利用できなくなる。
第 3 章では、すべてのオブジェクトに共通するメソッド、つまり Object クラスのメソッドについて、どのようにオーバーライドすべきかが述べられている。
(12 項の Comparable は例外)
equals をオーバーライドするときは一般契約に従う
equals をオーバーライドすべきとき
equals は、等価かどうか比較する必要がないとき、スーパークラスの equals で間に合っているときなどは、オーバーライドする必要はない。
つまり、それ以外の状況では、equals をオーバーライドする必要がある。
従うべき一般契約
equals をオーバーライドするときには、以下の同値関係を守る必要がある(一般契約)。
なお、以下の関係において、常に x != null, y != null, z!= null である。
- 反射的
x.equals(x) == true
- 対照的
x.equals(y) == trueならばy.equals(x) == true
- 推移的
x.equals(y) == trueかつy.equals(z) == trueならばx.equals(z) == true
- 整合的
x,yに変更がないとき、何度x.equals(y)を呼んでも同じ値が得られる
- 非 null 性
x.equals(null) == false
equals の実際の処理
equals の引数は以下のように処理していくとよい。
- 自分自身の参照と等価かどうか調べるために
==で検査 - 正しい型かどうか調べるために
instanceofを使って検査 - 引数を正しい型にキャスト
- 意味のある各フィールドに対して、等価かどうか検査
その他
equalsをオーバーライドするならhashCodeもオーバーライドするfloat,doubleのフィールドを比較するときは、それぞれFloat.compare,Double.compareを使うObject.equalsをオーバーライドする。オーバーロードしないOverrideアノテーションを使うことで、誤ったオーバーロードを防げる