Effective Javaを読むチャレンジ-項目8の2-

equalsメソッドの一般契約についての詳細解説部分を読む

反射性

x.equals(x)が成り立たないということはほとんどありません。意図的にプログラムしないかぎりは。コレクションのcontainsメソッドはコレクションに含まれる要素が何番目にあるかどうかを返すメソッドでして、要素がnullでない場合はequalsメソッドを使って一致するオブジェクトの位置を捜します。そのため反射性が成り立たないオブジェクトをコレクションに挿入すると、自分自身が見つけられないでしょう(-1を返します)と言っています。

対称性

x.equals(y)⇒y.equals(x)を意図せず破ってしまう可能性は結構あると言っています。例が分かりやすい。

推移性

x.equals(y)かつy.equals(z)⇒x.equals(z)を意図せず破ってしまう可能性も大いにあるという説明です。

この推移性の説明をざっくりまとめると、

  • equalsをオーバーライドするのは値クラスを作るとき
  • equalsの一般契約を守りつつ値クラスのサブクラスで値フィールドを追加する方法はない
  • ただし、値フィールドを追加するためのサブクラスを作るのではなく、コンポジションでカバーして回避する方法はある
  • しかしながら、抽象クラス(つまり何も値を持たないクラス)のサブクラスには、equalsの一般契約を守ったまま値を追加できる

となります。

整合性

x.equals(y)を何度実行してもその結果は変わらないことの保証。不変オブジェクトに対して可変オブジェクトの場合、例えば時間的変化をする、ネットワークなどの信頼できない資源に依存しているequalsメソッドにおいて整合性が保証されるとはいえない。

x.equals(null)はfalseを返す

非null性と本書では呼んでます。ポイントはx.equals(null)がNullPointerExceptionをスローすることは一般契約では認めてないのでやるべきでない。ただし、equalsをオーバーライドして引数のオブジェクトを使用する際にはそのクラスの型にキャストする必要があり、その前にinstanceof演算子による判定を行えば、instanceofの左辺がnullの場合はfalseを返すためにNullPointerExceptionを意識することはない、というところですね。無駄にnull検査しなくても上手くできるということです。

このあと総括に入りますが、ここまで読み切っていれば特に難しい説明はないですね。長い項目でしたが終了です。

広告
  • LINEで送る