Comment hashCode() et identityHashCode () fonctionnent à la fin?
comment Object.hashCode()
et System.identityHashCode()
travailler à l'arrière? identityHashCode()
renvoie-t-il la référence de l'objet? Est-ce que hashCode()
dépend de la ? de l'objet ? = = opérateur comment travailler à l'arrière.
Quelle est la différence entre hashCode()
et identityHashCode()
?
5 réponses
Comment faire de l'Objet.hashCode () et système.identityHashCode () travailler à l'arrière?
en supposant qu'il n'a pas été dépassé, la méthode Object.hashCode()
appelle simplement System.identityHashCode(this)
.
le comportement exact de System.identityHashCode(Object)
dépend de la mise en œuvre de la JVM. (La mise en œuvre effective des récentes JVM Hotspot est assez intelligente, mais je m'en écarte.)
Ne
identityHashCode()
retour à la référence de l'objet?
Pas de. Il renvoie un int
, et un int
ne peut contenir de référence. (Duh!)
cet entier retourné par identityHashCode
peut être lié à l'adresse (a) de la machine pour l'objet, ou il ne peut pas être 1 . La valeur retournée par identityHashCode()
est garantie de ne pas changer pour la durée de vie de l'objet. Cela signifie que le GC déplace un objet (après un appel identityHashCode()
) alors il ne peut pas utiliser la nouvelle adresse de l'objet comme hashcode d'identité.
est-ce que le hashCode() dépend du
?
de l'opérateur? ==
comment travailler à l'arrière.
ça n'a pas de sens. Il n'y a pas d'opérateur ? ==
ou ?==
en Java.
Quelle est la différence entre hashCode() et identityHashCode ()?
Ceci est partiellement expliqué ci-dessus. Autres différences:
-
la méthode
hashcode()
est une méthode en instance non finale et doit être remplacée dans toute classe où la méthodeequals(Object)
est remplacée. En revanche,identityHashCode(Object)
est une méthodestatic
et ne peut donc pas être dépassée. -
la méthode
identityHashCode(Object)
donne vous un identificateur d'un objet qui peut (en théorie) être utilisé pour d'autres choses que de hachage et les tables de hachage. (Malheureusement, il ne s'agit pas d'un unique identifier, mais il est garanti de ne jamais changer pour la durée de vie de l'objet.)
1 - pour les JVM de génération courante, il n'est pas du tout lié à l'adresse mémoire. Voir la réponse de @bestss.
identityHashCode () fonctionne comme cela ( et à partir de maintenant il n'a rien à faire à w/ l'adresse, esp. puisque les adresses sont 64bits long, ok alignées, et 61 )
vérifie s'il y a déjà généré un, si oui renvoie le. Vous pouvez supposer qu'il y a une place dans l'en-tête de l'objet pour ce int
;
sinon: génère un nombre aléatoire ( IIRC twister Marsaglia shift-xor algorithme), chaque fil natif a sa propre graine, donc aucune information partagée.
CAS le champ identityHashCode
dans l'en-tête de l'objet pour mettre à jour le numéro nouvellement généré. Si CAS success renvoie la valeur, sinon - le champ contient déjà un identityHashCode
généré .
vous pouvez voir le reste des réponses au sujet de la suppression du hashcode.
: si le javadoc indique toujours quelque chose à propos des adresses et du identityHashCode, quelqu'un doit mettre à jour il.
C'est assez spécifique à la mise en œuvre. La seule garantie que vous obtenez est
dans la mesure du possible, la méthode
hashCode
définie par la classeObject
renvoie des entiers distincts pour des objets distincts. (Ceci est typiquement implémenté en convertissant l'adresse interne de l'objet en un entier, mais cette technique d'implémentation n'est pas requise par le langage de programmation Java TM .)
(du Java 1.6 JavaDoc)
en théorie, cela signifie que les valeurs pourraient être déterminées arbitrairement et pourraient même être nulles pour chaque objet. Dans la pratique, c'est probablement un dérivé de l'adresse de l'objet. Bien sûr, vous devez être prudent à ce sujet. La JVM peut déplacer des objets si elle pense que c'est une bonne idée pendant une collecte des ordures, donc ce ne sera pas "juste" l'adresse mémoire. Il pourrait être tiré d'un mondial compteur, ou un hachage de l'emplacement de l'objet original, ou à partir d'un générateur de nombres aléatoires, etc.
identityHashCode
public static int identityHashCode (Object x)
retourne le même code de hachage pour l'objet donné que celui qui serait retourné par la méthode par défaut hashCode () , que la classe de l'objet donné l'emporte ou non sur hashCode(). Le code de hachage pour la référence nulle est zéro.
voir [ Java docs ]
donc si quelqu'un a dépassé hashCode()
méthode dans sa classe mais veulent toujours la valeur par défaut hashCode()
qui aurait été retourné par objet hashCode()
puis utiliser System.identityHashCode()
So, hashCode()
appels internes System.identityHashCode()
aussi longtemps que vous ne l'emportez pas dans votre classe, si vous outrepassez hashCode() il appellera votre implémentation.
beaucoup de réponses données ci-dessus, juste besoin d'ajouter quelques points.
Quand nous disons obj.hashCode()
le contenu de l'obj est considéré comme, d'autre part
dans System.identityHashCode(obj)
le contenu n'est pas pris en considération, donc identityHashCode
pour deux String
, int
(avec la même valeur) sera le différent mais Hashcode
sera le même.
dans le cas de String
pour obtenir identityHashCode
string pool joue un rôle important, exemple
Object s1 = "abcd";
Object s2 = new String("abcd");
Object s3 = "abcd";
System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());
//output:
identityHashCode : 2018699554 HashCode : 2987074
identityHashCode : 1311053135 HashCode : 2987074
identityHashCode : 2018699554 HashCode : 2987074
ici s1
et s3
pointant le même ref donc identityHashCode
pour s1 and s3
est toujours le même et s2
sera différent.
même pour int
aussi, IntegerCache
joue le rôle important pour obtenir le identityHashCode
Object s1 = 5;
Object s2 = new Integer(5);
Object s3 = 5;
System.out.println("identityHashCode : " + System.identityHashCode(s1) + " HashCode : " + s1.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s2) + " HashCode : " + s2.hashCode());
System.out.println("identityHashCode : " + System.identityHashCode(s3) + " HashCode : " + s3.hashCode());
//Output
identityHashCode : 2018699554 HashCode : 5
identityHashCode : 1311053135 HashCode : 5
identityHashCode : 2018699554 HashCode : 5