Ich habe die Implementierung von equals () und hashCode () in java.lang.Object untersucht.
Object.equals() Bei der Implementierung in JDK 8 werden lediglich die Referenzwerte wie unten gezeigt verglichen.
src/share/classes/java/lang/Object.java
public boolean equals(Object obj) {
return (this == obj);
}
src/share/classes/java/lang/Object.java#l149
Da der Referenzwert ein Zeiger auf ein Objekt ist, gibt Object.equals () nur dann true zurück, wenn es sich um dieselbe Instanz handelt.
The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.
Der Referenzwert (auch nur eine Referenz) ist ein Zeiger auf ein Objekt oder eine Null. null ist ein spezieller Referenzwert, der sich nicht auf ein Objekt bezieht.
Object.hashCode() hashCode () hängt von der JVM-Implementierung ab.
share/classes/java/lang/Object.java#l100
public native int hashCode();
share/classes/java/lang/Object.java#l100
Dies wird im folgenden Artikel ausführlich erläutert. How does the default hashCode() work?
Immerhin die Implementierung von OpenJDK in JVM
ist das, was sie sagten. XorShift ist ein Algorithmus, der (schnelle) Pseudozufallszahlen mit nur exklusiver logischer Summe und Bitverschiebung erzeugen kann. Nach der Generierung wird der Hash-Code in einem Bereich namens Object Header aufgezeichnet, der jeder Instanz gehört. Der zweite und nachfolgende Aufruf von hashCode () gibt den im Objektheader aufgezeichneten Hashcode zurück.
Der Code, der in OpenJDK8 Hash-Code generiert, lautet wie folgt.
src/share/vm/runtime/synchronizer.cpp
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
unsigned t = Self->_hashStateX ;
t ^= (t << 11) ;
Self->_hashStateX = Self->_hashStateY ;
Self->_hashStateY = Self->_hashStateZ ;
Self->_hashStateZ = Self->_hashStateW ;
unsigned v = Self->_hashStateW ;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
Self->_hashStateW = v ;
value = v ;
src/share/vm/runtime/synchronizer.cpp
Generieren Sie einen Hash-Code mit den Thread-Member-Variablen "_hashStateX" und "_hashStateW". Ich verstehe den xor-shift-Algorithmus nicht, aber indem ich die Werte von _hashStateX, _hashStateY und _hashStateW in alphabetischer Reihenfolge in die Variable mit dem vorherigen Namen verschiebe und _hashStateW zum nächsten Aufruf des generierten Hash-Codes mache Wir versuchen manchmal, eindeutige Werte zu generieren.
_hashState wird beim Erstellen des Threads wie folgt initialisiert.
src/share/vm/runtime/thread.cpp
_hashStateX = os::random() ;
_hashStateY = 842502087 ;
_hashStateZ = 0x8767 ; // (int)(3579807591LL & 0xffff) ;
_hashStateW = 273326509 ;
src/share/vm/runtime/thread.cpp
Object.equals () ist ein Vergleich von Referenzwerten. Der Wert von Object.hashCode () ist eine Zufallszahl, die beim ersten Aufruf in jeder Instanz generiert wird, und der zweite und nachfolgende Aufruf geben die generierte Zufallszahl zurück.
Recommended Posts