Je n'ai aucune idée pourquoi ces lignes de code renvoient des valeurs différentes:
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
La sortie est:
true
false
true
Pourquoi le premier revient-il true
et le second revient-il false
? Y a-t-il quelque chose de différent que je ne connais pas entre 127
et 128
? (Bien sûr, je sais que 127
< 128
.)
Aussi, pourquoi le troisième revient-il true
?
J'ai lu la réponse à cette question , mais je n'ai toujours pas compris comment elle peut revenir true
et pourquoi le code de la deuxième ligne revient false
.
.equals()
, sinon tous les paris sont ouverts.Réponses:
Il y a une différence frappante ici.
valueOf
renvoie unInteger
objet dont les valeurs peuvent être mises en cache entre -128 et 127. C'est pourquoi la première valeur renvoietrue
- elle est mise en cache - et la deuxième valeur renvoiefalse
- 128 n'est pas une valeur en cache, vous obtenez donc deuxInteger
instances distinctes .Il est important de noter que vous comparez des références avec
Integer#valueOf
, et si vous comparez une valeur qui est plus grande que ce que le cache prend en charge, elle ne sera pas évaluéetrue
, même si les valeurs analysées sont équivalentes (cas d'espèce:)Integer.valueOf(128) == Integer.valueOf(128)
. Vous devez utiliser à laequals()
place.parseInt
renvoie une primitiveint
. Ceci est la raison pour laquelle la troisième valeur revienttrue
-128 == 128
est évaluée, et bien sûr,true
.Maintenant, il arrive pas mal de faire ce troisième résultat
true
:Une conversion de déballage se produit en ce qui concerne l'opérateur d'équivalence que vous utilisez et les types de données que vous avez, à savoir,
int
etInteger
. Vous obtenez unInteger
duvalueOf
côté droit, bien sûr.Après la conversion, vous comparez deux
int
valeurs primitives . La comparaison se produit exactement comme vous vous y attendiez avec les primitives, vous finissez donc par comparer128
et128
.la source
List
. L'autre est une primitive, qui n'est qu'une valeur brute.==
. de toute façon, c'est clair maintenant.La
Integer
classe a un cache statique, qui stocke 256Integer
objets spéciaux - un pour chaque valeur entre -128 et 127. Dans cet esprit, considérez la différence entre ces trois.Cela fait (évidemment) un tout nouvel
Integer
objet.Cela renvoie une
int
valeur primitive après l'analyse duString
.C'est plus complexe que les autres. Il commence par analyser le fichier
String
. Ensuite, si la valeur est comprise entre -128 et 127, il renvoie l'objet correspondant à partir du cache statique. Si la valeur est en dehors de cette plage, elle appellenew Integer()
et transmet la valeur, de sorte que vous obtenez un nouvel objet.Maintenant, considérez les trois expressions de la question.
Cela renvoie true, car la
Integer
valeur dont la valeur est 127 est extraite deux fois du cache statique et comparée à elle-même. Il n'y a qu'un seulInteger
objet impliqué, donc cela revienttrue
.Cela revient
false
, car 128 n'est pas dans le cache statique. Un nouveauInteger
est donc créé pour chaque côté de l'égalité. Puisqu'il y a deuxInteger
objets différents , et==
pour les objets ne renvoie quetrue
si les deux côtés sont exactement le même objet, cela va êtrefalse
.Ceci compare la
int
valeur primitive 128 sur la gauche, avec unInteger
objet nouvellement créé sur la droite. Mais comme cela n'a pas de sens de comparer unint
à unInteger
, Java déballera automatiquement leInteger
avant de faire la comparaison; vous finissez donc par comparer unint
à unint
. Puisque la primitive 128 est égale à elle-même, cela revienttrue
.la source
Prenez soin de renvoyer les valeurs de ces méthodes. La méthode valueOf renvoie une instance Integer:
La méthode parseInt renvoie une valeur entière (type primitif):
Explication pour la comparaison:
Dans votre situation (selon les règles ci-dessus):
Cette expression compare les références au même objet car elle contient une valeur entière comprise entre -128 et 127 et renvoie donc
true
.Cette expression compare les références à différents objets car elles contiennent des valeurs entières non comprises dans <-128, 127>, donc elle renvoie
false
.Cette expression compare la valeur primitive (côté gauche) et la référence à l'objet (côté droit) afin que le côté droit soit déroulé et son type primitif sera comparé à la gauche afin qu'il retourne
true
.la source
==
, car ce sont des objets différents.Les objets entiers mettent en cache entre -128 et 127 sur 256 Integer
Vous ne devez pas comparer les références d'objet avec == ou ! = . Tu devrais utiliser . équivaut à(..) place, ou mieux - utilisez la primitive int plutôt que Integer.
parseInt : analyse l'argument de chaîne comme un entier décimal signé. Les caractères de la chaîne doivent tous être des chiffres décimaux, sauf que le premier caractère peut être un signe moins ASCII '-' ('\ u002D') pour indiquer une valeur négative. La valeur entière résultante est renvoyée, exactement comme si l'argument et la base 10 étaient donnés comme arguments à la méthode parseInt (java.lang.String, int).
Renvoie un objet Integer contenant la valeur extraite de la chaîne spécifiée lorsqu'elle est analysée avec la base donnée par le deuxième argument. Le premier argument est interprété comme représentant un entier signé dans la base spécifiée par le deuxième argument, exactement comme si les arguments étaient donnés à la méthode parseInt (java.lang.String, int). Le résultat est un objet Integer qui représente la valeur entière spécifiée par la chaîne.
équivalent à
radix - la base à utiliser pour interpréter s
donc si vous égalez
Integer.valueOf()
pour l'entier entre-128 à 127 il retourne vrai dans votre condition
pour
lesser than
-128 etgreater than
127 ça donnefalse
la source
Pour compléter les réponses données, prenez également note de ce qui suit:
Ce code imprimera également:
false
Comme l'utilisateur Jay l' a réclamé dans un commentaire pour la réponse acceptée, il faut faire attention lors de l'utilisation d'un opérateur
==
sur des objets, ici vous vérifiez si les deux références sont identiques, ce qui n'est pas, car ce sont des objets différents, bien qu'ils représentent même valeur. Pour comparer des objets, vous devez utiliser laequals
méthode à la place:Cela imprimera:
true
Vous pouvez demander, mais alors pourquoi la première ligne imprimée
true
? . En vérifiant le code source de laInteger.valueOf
méthode, vous pouvez voir ce qui suit:Si le paramètre est un entier compris entre
IntegerCache.low
(par défaut -128) etIntegerCache.high
(calculé à l'exécution avec une valeur minimale de 127), un objet pré-alloué (mis en cache) est renvoyé. Ainsi, lorsque vous utilisez 127 comme paramètre, vous obtenez deux références au même objet mis en cache et obteneztrue
la comparaison des références.la source