Java: entier est égal à ==

A partir de Java 1.5, vous pouvez à peu près interchanger Integer avec int dans de nombreuses situations.

Cependant, j’ai trouvé un défaut potentiel dans mon code qui m’a un peu surpris.

Le code suivant:

 Integer cdiCt = ...; Integer cdsCt = ...; ... if (cdiCt != null && cdsCt != null && cdiCt != cdsCt) mismatch = true; 

Il semble que l’on ne mette pas correctement l’adéquation lorsque les valeurs sont égales, bien que je ne puisse pas déterminer dans quelles circonstances. J’ai défini un point d’arrêt dans Eclipse et j’ai vu que les valeurs Integer étaient toutes les deux 137, et j’ai inspecté l’expression booléenne et il a dit que c’était faux, mais quand j’ai dépassé cette valeur.

Changer le conditionnel à:

 if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt)) 

résolu le problème.

Quelqu’un peut-il nous expliquer pourquoi cela s’est produit? Jusqu’à présent, je n’ai vu le comportement sur mon localhost que sur mon propre PC. Dans ce cas particulier, le code a réussi à faire passer environ 20 comparaisons, mais a échoué sur 2. Le problème était systématiquement reproductible.

S’il s’agit d’un problème courant, cela devrait causer des erreurs sur nos autres environnements (dev et test), mais jusqu’à présent, personne n’a signalé le problème après des centaines de tests exécutant cet extrait de code.

N’est-il toujours pas légitime d’utiliser == pour comparer deux valeurs Integer ?

En plus de toutes les bonnes réponses ci-dessous, le lien stackoverflow suivant contient de nombreuses informations supplémentaires. En fait, cela aurait répondu à ma question initiale, mais comme je ne mentionnais pas l’autoboxing dans ma question, cela ne figurait pas dans les suggestions sélectionnées:

Pourquoi le compilateur / JVM ne peut-il pas faire en sorte que l’autoboxing «fonctionne»?

La machine virtuelle Java met en cache les valeurs entières. == ne fonctionne que pour les nombres compris entre -128 et 127 http://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching

Vous ne pouvez pas comparer deux Integer avec un simple == ce sont des objects, donc la plupart du temps, les références ne seront pas les mêmes.

Il y a une astuce, avec Integer entre -128 et 127, les références seront les mêmes que la création automatique utilise Integer.valueOf() qui cache les petits entiers.

Si la valeur p étant cochée est true, false, un octet, un caractère dans l’intervalle \ u0000 à \ u007f, ou un nombre entier ou court entre -128 et 127, alors que r1 et r2 soient les résultats de deux conversions de boxe de p. C’est toujours le cas que r1 == r2.


Ressources :

  • JLS – Boxe

Sur le même sujet:

  • box automatique vs boxe manuelle java

Le problème est que vos deux objects Integer ne sont que des objects. Ils ne correspondent pas parce que vous comparez vos deux références d’object, pas les valeurs qu’il contient. Evidemment, .equals est remplacé pour fournir une comparaison de valeur par opposition à une comparaison de référence d’object.

Integer fait référence à la référence, c’est-à-dire que lorsque vous comparez des références, vous comparez si elles pointent vers le même object, et non pas la valeur. Par conséquent, le problème que vous voyez. La raison pour laquelle cela fonctionne si bien avec les types plain int est qu’il déballe la valeur contenue dans le Integer .

Puis-je append que si vous faites ce que vous faites, pourquoi commencer par la déclaration if ?

 mismatch = ( cdiCt != null && cdsCt != null && !cdiCt.equals( cdsCt ) ); 

“==” compare toujours l’emplacement de mémoire ou les références d’object des valeurs. égal à méthode toujours comparer les valeurs. Mais égalise aussi indirectement l’opérateur “==” pour comparer les valeurs.

Entier utilise le cache Integer pour stocker les valeurs de -128 à +127. Si l’opérateur == est utilisé pour vérifier les valeurs entre -128 et 127, il renvoie true. pour autre que ces valeurs, il retourne faux.

Reportez le lien pour des informations supplémentaires