J'ai étudié l'implémentation de equals () et hashCode () dans java.lang.Object.
Object.equals() L'implémentation dans JDK 8 compare simplement les valeurs de référence comme indiqué ci-dessous.
src/share/classes/java/lang/Object.java
public boolean equals(Object obj) {
return (this == obj);
}
src/share/classes/java/lang/Object.java#l149
Puisque la valeur de référence est un pointeur vers un objet, Object.equals () renvoie true uniquement s'il s'agit de la même instance.
The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.
La valeur de référence (également juste une référence) est un pointeur vers un objet ou null. null est une valeur de référence spéciale qui ne fait pas référence à un objet.
Object.hashCode() hashCode () dépend de l'implémentation JVM.
share/classes/java/lang/Object.java#l100
public native int hashCode();
share/classes/java/lang/Object.java#l100
Il est expliqué en détail dans l'article ci-dessous. How does the default hashCode() work?
Après tout, l'implémentation d'OpenJDK dans JVM
est ce qu'ils ont dit. XorShift est un algorithme qui peut générer des nombres pseudo-aléatoires (rapides) avec uniquement une somme logique exclusive et un décalage de bits. Une fois généré, le code de hachage est enregistré dans une zone appelée en-tête d'objet, qui appartient à chaque instance. Le deuxième appel et les suivants à hashCode () renverront le code de hachage enregistré dans l'en-tête d'objet.
Le code qui génère le code de hachage dans OpenJDK8 est le suivant.
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
Générez un code de hachage à l'aide des variables de membre de thread _hashStateX
et _hashStateW
.
Je ne comprends pas l'algorithme xor-shift, mais en déplaçant les valeurs de _hashStateX, _hashStateY et _hashStateW vers la variable avec le nom précédent dans l'ordre alphabétique et en faisant de _hashStateW le code de hachage généré, le prochain appel Nous permettons parfois de générer des valeurs uniques.
_hashState est initialisé comme suit lorsque le thread est créé.
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 () est une comparaison de valeurs de référence. La valeur de Object.hashCode () est le nombre aléatoire généré au premier appel de chaque instance, et le deuxième appel et les suivants renvoient le nombre aléatoire généré.
Recommended Posts