Integer parfois égaux, parfois différents

Integer parfois égaux, parfois différents - Java - Programmation

Marsh Posté le 18-08-2010 à 13:31:42    

Bonjour
 
J'ai fait un petit programme auquel je ne comprend rien du tout.  
 

Code :
  1. public class TestInteger
  2. {
  3.     public static void main (String args[])
  4.     {
  5.         Integer x1 = 124;
  6.         Integer x2 = 124;
  7.         while (x1 == x2) {
  8.             System.out.println (x1 + " == " + x2 + " : " + (x1 == x2));
  9.             x1 += 1;
  10.             x2 += 1;
  11.         }
  12.     }
  13. }


 
Quand je lance ce programme j'obtiens:
 

Code :
  1. 124 == 124 : true
  2. 125 == 125 : true
  3. 126 == 126 : true
  4. 127 == 127 : true


 
Pourquoi, avec l'auto-unboxing y'a égalité entre -128 et +127 (càd le domaine de définition du type byte) et plus en dehors ? Si vous avez des pointeurs sur des docs qui expliquent cela je suis preneur... Merci d'avance

Reply

Marsh Posté le 18-08-2010 à 13:31:42   

Reply

Marsh Posté le 18-08-2010 à 15:14:14    

http://www.owasp.org/index.php/Java_gotchas
C'est une histoire d'optimisation pour les petites valeurs, souvent employées:

Citation :

256 Integer objects are created in the range of -128 to 127 which are all stored in an Integer array. This caching functionality can be seen by looking at the inner class, IntegerCache, which is found in Integer:  
...
So when creating an object using Integer.valueOf or directly assigning a value to an Integer within the range of -128 to 127 the same object will be returned. Therefore, consider the following example:


A+,


Message édité par gilou le 18-08-2010 à 15:18:03

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-08-2010 à 15:18:04    

Au risque de dire une connerie énorme, mais bon j'suis plus à ca pret: on est d'accord que == teste l'égalité entre pointeurs vu que Integer est un objet, donc le résultat du test dépend de la facon dont la JVM fonctionne.

 

Donc à mon avis: ta JVM stocke les pointeurs sur les x entiers possibles du type byte (-128 à +127) pour une raison quelconque (optimisation interne ou autre, on peut imaginer que ces nombres-là sont les plus utilisés donc ya des mécanismes spéciaux pour optimiser leur utilisation) mais pas plus que ca pour une autre raison quelconque (par exemple créer tous les entiers possibles ca prendrait de la place pour rien). Et elle utilise ces pointeurs automatiquement quand "toi le programmeur" tu te sers de ces nombres. Bonne chance pour trouver de la doc là-dessus si c'est bien JVM-dépendant.

 

Maintenant histoire de troller un peu, j'ai envie de dire que je vois pas trop de cas où ca a un intéret de comparer les pointeurs d'objets Integer... Mais du coup c'est intéressant, si tu en as un sous la main, on peut p'tetre en discuter.

 

Edit:  [:kelso burn] et en mieux expliqué et plus court... Cela dit j'avais vu juste

Message cité 1 fois
Message édité par lasnoufle le 18-08-2010 à 15:20:45

---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 18-08-2010 à 15:21:27    

A la base, comme il a une classe, s'il veut comparer des objets, il faut faire appel aux méthodes ad-hoc de la classe, donc equals ici, et non pas ==.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-08-2010 à 16:04:52    

lasnoufle a écrit :

Maintenant histoire de troller un peu, j'ai envie de dire que je vois pas trop de cas où ca a un intéret de comparer les pointeurs d'objets Integer... Mais du coup c'est intéressant, si tu en as un sous la main, on peut p'tetre en discuter.


Il est rare que comparer des refs ait le moindre intérêt (sauf à les comparer avec null à la limite), mais dans la mesure où l'utilisateur (du langage) doit pouvoir customiser son test d'égalité et où les designers de java ont déclaré que l'overloading d'opérateurs par l'utilisateur était anathème, ben tu te retrouves à devoir utiliser equals() pour les tests d'égalité.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 19-08-2010 à 03:33:59    

deux choses :
- primitives != wrapper
- l'utilisation directement de primitives dans ton cas est préférable car il existe des effets de bord a l'autoboxing/unboxing
 
http://www.javabeat.net/articles/3 [...] -50-2.html


---------------
Plop !
Reply

Marsh Posté le 30-08-2010 à 16:37:49    

Merci pour ces réponses. Je ne comprends toujours pas la raison du choix de cette limite (plage d'un byte) mais bon, on va faire avec. Ce qui me gêne le plus (et qui a été mentionné) c'est le comportement variable de == en fonction de la valeur de ce qu'on compare. Je préférerais que ça ne marche jamais ou toujours, mais là ça me laisse perplexe..  
 
Merci encore de votre aide
 

Reply

Marsh Posté le 30-08-2010 à 18:20:44    

Citation :

c'est le comportement variable de == en fonction de la valeur de ce qu'on compare

Le comportement n'est pas variable, il répond effectivement correctement selon que l'objet de la classe Integer est le même ou non, et l'implémentation fait que pour des valeurs entre -128 et +127, il n'y a qu'un seul objet de la classe Integer de créé.
 
Si vous vouliez comparer les valeurs des objets en question, il fallait utiliser la méthode ad-hoc précisée dans la classe Integer, ie equals:
Integer x1 = 124;
Integer x2 = 124;
while (x1.equals(x2))...
Et si vous tenez a utiliser ==, il fallait utiliser des types primitifs et non des classes:
int x1 = 124;
int x2 = 124;
while (x1 == x2)...
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed