The HIRO Says

If you smell what The HIRO is cooking!!!

hashCode() メソッドの実装(2)−Eclipseに自動生成させてみた

equals() メソッドと同様に、Eclipse(v3.2.0)に hashCode() メソッドを自動生成させてみました。


生成されたコード

    @Override
    public int hashCode() {
        final int PRIME = 31;
        int result = super.hashCode();
        result = PRIME * result + (booleanValue ? 1231 : 1237);
        result = PRIME * result + charValue;
        result = PRIME * result + *1;
        long temp;
        temp = Double.doubleToLongBits(doubleValue);
        result = PRIME * result + (int) (temp ^ (temp >>> 32));
        result = PRIME * result + Float.floatToIntBits(floatValue);
        result = PRIME * result + intValue;
        result = PRIME * result + (int) (longValue ^ (longValue >>> 32));
        result = PRIME * result + shortValue;
        result = PRIME * result + *2;
        return result;
    }

感想

  1. このように定数 PRIME を定義する方が、比較毎に "31" と書くよりも好ましいと思います。
  2. super.hashCode() は宜しくない!(理由は後述)
  3. booleanValue の "1231" と "1237" が意味不明…
  4. byteValue の比較が何故か抜けている!(このせいでテスト失敗)
  5. 上記以外は、自力で実装した内容と同じでした。

super.hashCode() の宜しくないところ

今回 JDK1.5.0_19 で試したところ、super.hashCode()(java.lang.Object#hashCode())は、オブジェクト毎に異なる値を返してきました。
そのため、super.hashCode() の値を基数として使用してしまうと、field 値が同じならば同一の値を返すという hashCode() の規約に反することになってしまいます。
そのため、super.hashCode()(java.lang.Object#hashCode())は呼ばない方がよいようです。


*1:dateValue == null) ? 0 : dateValue.hashCode(

*2:stringValue == null) ? 0 : stringValue.hashCode(