IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Java Discussion :

Java & Autoboxing


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Janvier 2009
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 46
    Par défaut Java & Autoboxing
    Bonjour à tous,

    Je fais appel à vos talents pour m'expliquer ce qui se passe dans le bout de code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Integer i1 = 1000;
    	Integer i2 = 1000;
    	if(i1 != i2) System.out.println("i1 non égal à i2");
     
    	Integer i3 = 127;
    	Integer i4 = 127;
    	if(i3 != i4) System.out.println("i3 non égal à i4");
    A l'exécution il m'affiche bien "i1 non égal à i2". Jusque la d'accord, puisque i1 et i2 sont 2 objets différents, et ce sont ici les références qui sont comparées.

    Cependant à ma grande surprise, il n'affiche pas "3 non égal à i4" !
    Par contre si je fixe la valeur des variables i3 et i4 à 128 (au lieu de 127), la il m'affiche bien "i3 non égal à i4" !

    Conclusion, si 2 Integer sont égaux et inférieurs à 128, java les considére égaux. Cependant si ils sont supérieurs à 128, ils ne sont plus égaux...

    Si quelqu'un peut m'éclairer...

  2. #2
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Au risque de te surprendre je dirais que ton résultat est... normal

    En fait, la classe Integer utilise un cache pour les Integer entre -128 et 127. C'est ce qui explique le comportement que tu observes... Pour les Integer hors de ces bornes, c'est une création d'objet différent.

    J'ajouterais que l'autoboxing fait appel a la fonction de la classe Integer :
    public static Integer valueOf(int i)

    Et si tu regardes sa source, tu verras le code correspondant au cache

    a+

  3. #3
    Membre averti
    Inscrit en
    Janvier 2009
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 46
    Par défaut
    Bon je répond moi même à ma question...

    Java crée par défaut un pool d'Integer, compris entre les valeurs -127 et 127, et ce afin d'économiser la mémoire.

    Et donc quand on instancie un Integer dans cette plage, on ne crée par de nouvelle objet, mais la référence pointe vers la valeur déja stockée dans le pool de connexion.

    Donc Integer(127) et Integer(127) ont les mêmes adresses mémoires. Contrairement à Integer(128) et Integer(128).


    edit@hwoarang : effectivement, tu m'as devancé, et je n'avais pas pris assez de temps pour chercher, merci

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par romano62880 Voir le message

    Donc Integer(127) et Integer(127) ont les mêmes adresses mémoires. Contrairement à Integer(128) et Integer(128).
    Attention, new Integer(127) et new Integer(127) ont bien des adresses différentes. C'est Integer.valueOf(127) qui fait appel à une cache!

  5. #5
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    181
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2011
    Messages : 181
    Billets dans le blog
    1
    Par défaut
    slt,
    Pour tester les deux entiers essaye la méthode intValue () de la class Integer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Integer i1 = 1000;
    	Integer i2 = 1000;
    	if (i1.intValue () != i2.intValue ()) System.out.println("i1 non égal à i2");
    	Integer i3 = 127;
    	Integer i4 = 127;
    	if(i3.intValue () != i4.intValue ()) System.out.println("i3 non égal à i4");
    Ce que tu a fait toi, c'est crée deux instances de la class Integer, en les initialisant, tu a modifié les valeurs de chacun de leurs attributs value, qui est de type int, (i1.value == 1000, i2.value == 1000), ensuite, si tu fait Tu vas tester les deux references des instances, i1 et i2, par contre si tu met, i1.intValue (), la méthode intValue () vas retournée la valeur contenue dans l’attribue value de l'instance i1, donc tester deux entier, pas deux references des instances de la class Integer .
    A+ .

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par mohamine1989 Voir le message
    Pour tester les deux entiers essaye la méthode intValue ()
    Oui, ou equals(), comme à chaque fois qu'on veut comparer des objets.
    Mais là la question c'était pas s'il fallait utiliser == ou autre chose, mais pourquoi des fois les objets c'est les mêmes et des fois pas. Une sorte de curiosité scientifique.

    Citation Envoyé par mohamine1989 Voir le message
    Ce que tu a fait toi, c'est crée deux instances de la class Integer, en les initialisant, tu a modifié les valeurs de chacun de leurs attributs value, qui est de type int, (i1.value == 1000, i2.value == 1000), ensuite, si tu fait Tu vas tester les deux references des instances, i1 et i2, par contre si tu met, i1.intValue (), la méthode intValue () vas retournée la valeur contenue dans l’attribue value de l'instance i1, donc tester deux entier, pas deux references des instances de la class Integer .
    J'ai pas trop compris ce que tu essaies de dire, mais, comme nous l'avons vu, il a créé trois instances de la classe Integer, pas deux, pas quatre.
    Et Integer étant une classe immutable on ne peut pas changer la valeur de son attribut value après que l'objet a été instancié.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre averti
    Inscrit en
    Janvier 2009
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 46
    Par défaut
    Merci pour vos réponses.

    Tout comme le dit thelvin, je ne cherchais pas ici à tester 2 entiers, je me posais simplement la question, à savoir pourquoi quand on crée deux objets Integer(127), ceux-ci avaient la même adresse mémoire, et pourquoi quand on en crée 2 Integer(128) ceux-ci avaient des adresses différentes.
    Je sais bien qu'en utilisant equals() ou intValue() il compare la valeur de l'entier.

    @tchize_ : tu fais erreur, deux objets new Integer(127) et new Integer(127) ont bien la même adresse mémoire ! C'est ce qu'on vient d'expliquer.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Service de nommage java C++
    Par Anonymous dans le forum CORBA
    Réponses: 3
    Dernier message: 15/04/2002, 12h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo