/** * GenericContractでは、hashCode()メソッドのオーバーライドを行っていないので、 * 「等しいオブジェクトは、同じハッシュコードを持たなければならない。」という * 制約に違反してしまうので、このサンプルで、hashCode()をオーバーライドする。 * もし、このままであると、HashMap, HashSet, Hashtableを含むハッシュ系のコレクションで * 適切な動作が出来なくなる。 */ package com.util; /** * 論理的等価性(logical equality)が必要で、且つスーパークラスがそれに対応する * equals()メソッドを実装していない場合に、equals()メソッドを実装する。 * また、equals()メソッドを実装する際には、一般契約(Generic Contract)を守らなければ * ならない。この契約違反をした場合、JVM実装はどのような振る舞いをするか分からない。 * 一般契約一覧 * * * @see 実装参考 Effective Java 第3章項目7 equalsをオーバーライドする時は一般契約に従う * * @author s-okita */ public class GenericContract2 { private int status; public GenericContract2() { status = 0; } public GenericContract2(int status) { this.status = status; } /** * reflexive contract * Symmetric contract */ public boolean equals(Object obj) { // 下記、Exceptionを生成しないように実装する事が、equals一般契約である。 // NullPointerException. // ClassCastException // 最初に行うのはnullチェックではなく、instanceof // これにより、NullPointerException, ClassCastExceptionを回避する。 //if (obj != null) { if (obj instanceof GenericContract2) { // for debug if (this == obj) { // reflexive return true; } else { // Symmetric if (this.status == ((GenericContract2)obj).getStatus()) { return true; } } } return false; } public int hashCode() { // ここでHash関数を利用すべきではない。 // Hash関数に依存するため、またHash関数などは数学的要素が // 多数を占めるのでパフォーマンスの影響を受けかねない。 //return new Random().nextInt(); //return 1; int result = 17; // 17,37 are a prime number. result = 37 * result + status; return result; } /** * @return */ public int getStatus() { return status; } /** * @param i */ public void setStatus(int i) { status = i; } }