2017-11-29 15 views
0
class Employee { 
    String name; 

    Employee(String name) { 
    this.name = name; 
    } 
    // hashCode method is not overridden 
} 

public class HashCodeConfusion { 
    public static void main(String[] args) { 
    Employee emp = new Employee("ABC"); 
    Employee emp1 = new Employee("ABC"); 

    if (emp == emp1) { 
     System.out.println("Employee Same reference"); 
    } else { 
     System.out.println("Employee Different reference"); 
    } 
    if (emp.hashCode() == emp1.hashCode()) { 
     System.out.println("Employee Same hash code"); 
    } else { 
     System.out.println("Employee Different hash code"); 
    } 

    // ----------------------------------- 

    String str = new String("ABC"); 
    String str1 = new String("ABC"); 

    if (str == str1) { 
     System.out.println("String Same reference"); 
    } else { 
     System.out.println("String Different reference"); 
    } 
    if (str.hashCode() == str1.hashCode()) { 
     System.out.println("String Same hash code"); 
    } else { 
     System.out.println("String Different hash code"); 
    } 
    } 
} 

質問/混乱オブジェクト: ObjectクラスのデフォルトのhashCodeを考慮にオブジェクト参照を取るだけでなく、中身しているように見える 、なぜそうでないだろう従業員クラスのオブジェクトと同じ名前が別のハッシュコードで出てくるのでしょうか? Objectクラスのデフォルトの実装で、内容のみに基づくハッシュアルゴリズムがある場合、hashCodeメソッドをオーバーライドする必要はありません。ただし、同等のパラダイムがビット単位の互換性に合致する限りです。他のクラス対文字列のハッシュコードは

この混乱をクリアするには?

+0

デフォルトのハッシュコードは_alone_の参照に生成されます。コンテンツはここでは無関係です。しかし、 'String'やプリミティブラッパーのような他のクラスは、独自のコンテンツベースの実装を提供します。多くの場合、クラスのすべてのフィールドが 'equals()'と 'hashCode()'によって使われるわけではないので、これをそのまま使うことはできません(例としてjava.util.Dateを見てください)。ハッシュコードを提供するために 'cdate'か' fastTime'のどちらかを使います - 全てのフィールドを使っているデフォルト実装はそのことを知らないでしょう)。 – Thomas

+0

"コンテンツの内容だけでなくオブジェクトの参照も考慮に入れています。 –

答えて

1

デフォルトのhashCode()はに基づいていないであり、システム内のどのアドレスでもありません。これは、ヘッダに格納されたランダムに生成された番号です。これにより、オブジェクトはhashCode()を変更せずに移動でき、hashCodeは合理的にランダムです。

注:マイナーGC後

  • 、Eden領域は空で、作成された第一の目的は、同じアドレスに常にあります。それは同じhashCodeを持っていません。
  • オブジェクトはデフォルトで8バイトの境界に作成されるため、下位3ビットはすべて000になり、hashCodeには役立ちません。圧縮されたOopsを使用する場合、下位ビットは格納されないかもしれませんが、あまりランダムではありません。
  • Unsafeを使用すると、格納されているhashCodeを読み取って上書きすることもできます。 OracleJVM/OpenJDKでは、hashCodeはオブジェクトの先頭から1バイトずつ格納されます。
  • hashCodeの格納に使用されるビットは、ベイズド・ロックにも使用されます。オブジェクトの組み込みのhashCodeを取得すると、バイアスされたロックは使用されません。
  • System.identityHashCode(x)IdentityMapが使用する)を使用して、任意のオブジェクトのシステムhashCodeを取得できます。
関連する問題