Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

Comparaison entre Integer/String


Sujet :

avec Java

  1. #1
    Futur Membre du Club
    Comparaison entre Integer/String
    Bonjour,

    J'aimerais connaitre la raison de l'output de mon code :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
      Integer i1 = 128;
      Integer i2 = 128;
      Integer i3 = 42;
      Integer i4 = 42;
      String s1 = "EPL";
      String s2 = new String("EPL");
     
      System.out.println(i1 == i2);
      System.out.println(i3 == i4);
      System.out.println(s1 == s2);


    Le résultat est false, true et false. Je comprends bien que deux objets ne peuvent pas être comparé par "==" car ils ne se situent pas à la même adresse et que pour les objets il faut utiliser equals plutôt mais quid d'un des trois résultats qui est true ?

    Merci !!

  2. #2
    Modérateur

    Hello,

    il ne faut pas utiliser == parce que ça ne fait pas ce que tu veux.

    Mais, en termes de résultats, ce sont des booléens : il n'existe que deux résultats possibles. Juste parce que ça ne fait pas ce que tu veux, ne garantit pas que ça ne va pas, par hasard, donner la même réponse que ce que tu veux.

    Le problème c'est qu'utiliser == ne donnera pas toujours le bon résultat. Le fait que ça donne parfois le bon résultat, n'est pas spécialement utile.

    Bon, cette remarque étant faite, voyons ce qui se passe.

    - Avec tes Strings : quand on utilise le mot-clé new, c'est pour créer un nouvel objet. Le but est donc que l'objet obtenu ne soit pas le même qu'un autre. Donc qu'il ne soit == avec aucun autre que tu aies pu avoir jusque-là. Si tu avais fait new Integer, tu aurais eu false partout tout pareil.

    - Avec tes Integers : tu n'as pas utilisé new, donc pas demandé à ce que l'objet obtenu soit un nouvel objet. Si par hasard Java a des objets Integer avec la bonne valeur qui traînent, il a le droit de te les refourguer.

    Dans un cas (42), il te refourgue le même Integer pour les deux variables. Et pour un autre (128), il te crée des nouveaux objets à chaque fois (ou en tout cas, de ce que tu peux en voir, au moins une fois,) donnant deux objets différents pour les deux variables.

    Qu'est-ce qui mène à ça, eh bien, il faut se rappeler qu'un Integer, c'est juste un objet qui contient un int, sans changer le int contenu, et c'est tout. Ça prend quand même beaucoup de mémoire, de temps de construction et de maintenance, un objet, juste pour faire ça. C'est un peu gâcher.

    Surtout qu'assez souvent, les Integers utilisés c'est un peu toujours les mêmes, zéro, un, moins un, dix, et des valeurs pas très grandes.

    Eh ben Java utilise un petit truc : il garde de côté, en permanence, 256 objets Integer, correspondant aux 256 valeurs les plus proches de zéro : de -128 à 127. Du coup, quand tu construits un Integer sans new, si l'Integer a l'une des valeurs en question, il va juste te donner l'objet qu'il a pour ça. Et il te donnera toujours ce même objet.

    Mais il ne peut pas faire comme ça avec toutes les valeurs possibles de int, et c'est compliqué de "garder de côté" des valeurs déjà créées. Alors si la valeur demandée n'est pas de -128 à 127, il crée juste un nouvel objet avec la valeur voulue, sans se poser de question. Note que Java n'est pas obligé de faire ça. Si un jour Java trouve un moyen efficace de réutiliser des objets Integer de valeur connue, alors il aura parfaitement le droit de le faire. Tu ne peux pas compter sur le fait qu'il ne le fait pas. Mais à ce jour, ce n'est pas le cas.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Futur Membre du Club
    Bonjour,

    Et bien un tout grand merci pour cette réponse MAGISTRALE !! Peu de temps après avoir poster la question sur le forum, j'avais lu sur un forum anglais cette histoire de "caching" qui est que Java garde en mémoire cache un certain intervalle d'entier comme tu l'as si joliment expliquer.

    Ta réponse a clairement clarifier tout le problème. Par ailleurs j'ai lu aussi qu'il faudrait donc pour être rigoureux implémenter une méthode equals (plutôt faire un override et modifier celle de java pour l'usage qu'on veut en faire) afin d'éviter les soucis.

    Une dernière question mais j'ouvrirais un nouveau sujet si ce n'est pas approprié, j'ai du mal avec la théorie sur les appels de méthode avec argument c'est à dire que dans certains cas l'argument est une copie de la valeur de notre objet de référence donc peu importe ce que fais la méthode elle ne pourra jamais modifier un objet entièrement mais seulement partiellement.

    J'avais lu des exemples de code comme quoi si on passe un int en argument dans une méthode et qu'a l'intérieur de la méthode elle modifie la valeur de notre int et bien si on Print sur la console à nouveau notre int de départ sa valeur n'aura pas été modifier. Pareil pour les strings et pour les array on peut modifier partiellement une valeur du tableau a l'intérieur de la méthode mais si on modifie le tout cela ne sera pas pris en compte..

    J'espère que c'est plus au moins clair ce que j'essaye de vous demander, donc j'aimerais savoir ou je pourrais bien apprendre cette partie théorique la (ainsi que la portée des variables) pour pouvoir être à l'aise dans mon code ?

    Merci infiniment

  4. #4
    Modérateur

    Oui bien sûr, c'est la grande question du passage par copie ou par référence, on a l'habitude. Surtout qu'il est vrai que Java et son approche particulière sur les objets, a de quoi embrouiller le débutant.

    Enfin, je fais le kéké et je dis qu'on a l'habitude, mais j'ai bien peur de ne pas trop savoir où te diriger. Je n'ai pas trouvé d'explication bien faite dans la FAQ. Googler la question donne les explications nécessaires, mais aucune page que je ne recommanderais vraiment (surtout pas celle d'Open classroom : il y a des exemples complètement erronés et du coup ça va être compliqué de comprendre).

    Toujours est-il que pour demander l'aide de tout le monde, et éventuellement qu'on s'essaie à une explication en français si on trouve pas de page bien, il vaut mieux ouvrir une nouvelle question, oui.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre actif
    Citation Envoyé par thelvin Voir le message


    Eh ben Java utilise un petit truc : il garde de côté, en permanence, 256 objets Integer, correspondant aux 256 valeurs les plus proches de zéro : de -128 à 127. Du coup, quand tu construits un Integer sans new, si l'Integer a l'une des valeurs en question, il va juste te donner l'objet qu'il a pour ça. Et il te donnera toujours ce même objet.

    Mais il ne peut pas faire comme ça avec toutes les valeurs possibles de int, et c'est compliqué de "garder de côté" des valeurs déjà créées. Alors si la valeur demandée n'est pas de -128 à 127, il crée juste un nouvel objet avec la valeur voulue, sans se poser de question. Note que Java n'est pas obligé de faire ça. Si un jour Java trouve un moyen efficace de réutiliser des objets Integer de valeur connue, alors il aura parfaitement le droit de le faire. Tu ne peux pas compter sur le fait qu'il ne le fait pas. Mais à ce jour, ce n'est pas le cas.
    Pour info , le cache des valeurs d'integer a des borne qui peuvent être augmenter lors du lancement de la VM .

###raw>template_hook.ano_emploi###