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

Langage Java Discussion :

String référence/type primitif


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2014
    Messages : 80
    Par défaut String référence/type primitif
    Bonjour j'ai quelques questions concernant les réferences en java, merci de m'éclaircir s'il vous plait.

    1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     String a,b;
     
       		a = new String("lol");
       		b = a;
       		a = "louis";
     
       		System.out.println(b);      // là ça m'affiche lol à la place de louis, je ne comprends pas les objets a et b contiennent pourtant la même 
                                                            référence.
    2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     String s1 = "Hello";
       		String s2 ="Hel";
       		s2 = s2 + "lol";
     
       		System.out.println(s1 == s2);   // là vu que je n'ai pas utilisé de new s1 contient la chaîne hello et pas une référence et s2 contient 
                                                                     également la chaîne hello pourtant ça m'affiche faux
    Ps: je sais que pour comparer les chaînes de caractère il faut utiliser la méthode equals mais c'est pour comprendre les subtilités.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Premier cas

    Tu créés une (instance de) String dont tu mets la référence dans la variable a.
    Puis tu mets le contenu de a dans b, donc la référence de la String. b et a contiennent la même référence de String.
    Puis tu mets la référence d'une autre (instance de) String dans a. Ca n'affecte en rien b, ni la chaine référencée par b.

    Quand tu affiches b, ça affiche la chaîne référencée par b, donc "lol".

    Second cas

    C'est bien pour cette raison qu'on ne doit pas utiliser == pour tester l'égalité des chaines : parce que ça compare des références et pas des chaines. s1 et s2 sont 2 instances différentes. Cela dit equals() aurait donné false également, parce que "Hello" n'est pas égal à "Hellol".

    Même si tu avais écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    String s1 ="Hel";
    String s2 = s1 + "lol";
    s2 = s2 + "lol";
     
    System.out.println(s1 == s2);
    ça aurait affiché false. Parce que la concaténation de 2 variables créé forcément une nouvelle instance de String. Donc la référence contenue dans s2 ne peut être égale à la référence contenue dans s1.

    A noter, toutefois, que dans le cas suivant, le résultat est true, parce que le compilateur résout la concaténation (on concatène des constantes). Et l'affectation utilise un cache qui fait que la même référence est mise dans les 2 variables.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    String s1 ="Hel" +"lol";
    String s2="Hel" +"lol";
     
    System.out.println(s1 == s2);
    C'est pour cette raison qu'il vaut mieux utiliser equals() pour tester l'égalité, parce qu'il faut vraiment bien connaitre la façon d'instancier les chaines et l'affectation des variables qui les référencent pour utiliser le ==, ce qu'il n'est pas toujours évident de savoir.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre émérite Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Par défaut
    Citation Envoyé par wear12 Voir le message
    Bonjour j'ai quelques questions concernant les réferences en java, merci de m'éclaircir s'il vous plait.
    Si tu décomposes ton code :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    a = new String("lol");
    a -> ["lol"], b -> null
    a -> ["lol"], b -> ["lol"]
    Le résultat est que b pointe vers la valeur pointé par a, et non vers la variable locale a, et heureusement, sinon il serait très du de faire des permutations...
    a -> ["louis"], b -> ["lol"]

    Donc le resultat que tu as en affichant b est logique
    [/CODE]

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     String s1 = "Hello";
       		String s2 ="Hel";
       		s2 = s2 + "lol";
     
       		System.out.println(s1 == s2);   // là vu que je n'ai pas utilisé de new s1 contient la chaîne hello et pas une référence et s2 contient 
                                                                     également la chaîne hello pourtant ça m'affiche faux
    Ici, le signe == permet de verifier si les deux objets pointent vers le même object, ce qui n'est pas le cas. Tu as beau ne pas avoir fait de new pour s1, la notation "Hello" doit le faire de manière implicite. Et la concatenation de "Hel" et de "lol" (qui ne donne pas "Hello" au passage), instancie un nouvel objet.

    Citation Envoyé par wear12 Voir le message
    Ps: je sais que pour comparer les chaînes de caractère il faut utiliser la méthode equals mais c'est pour comprendre les subtilités.
    Attention, contrairement à ce que laisse penser dans le titre, les chaines de caratères ne correspondent pas à un type primitif en java, mais bien à un objet. La preuve, tu peux directement leur appliquer des méthodes. Essaie de faire pareil avec une entier, qui est un type primitif, ca ne marchera pas !

  4. #4
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    En java, quand tu fais (objet1 == objet2), tu compares les instances (plus précisemment l'adresse mémoire). Ca veut dire que ce test sera faux à partir du moment ou tu crées 2 objets (en utilisant new).

    La classe String est particuliere. Quand tu instancies un String implicitement, en utilisant String s = "mon string";, la machine virtuelle utilise un pool spécial ou sont stockées les String. C'est pour ca que si tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String s1 = "mon string";
    String s2 = "mon string";
    // s1 == s2 sera vrai parce que correspondant à la meme instance du pool de string. Tu auras le meme comportement pour les Integer inferieurs à 127 (si je me souviens bien).

    Pour revenir à tes exemples, quand tu fais String a = new String("lol");, tu forces la machine virtuelle à instancier un nouveau String. Ainsi, si tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String s1 = new String("mon string");
    String s2 = "mon string";
    // s1 == s2 sera faux.

    Et dans le 2e exemple, quand tu fais des concatenations de chaines, en pratique, la machine virtuelle va instancier un objet StringBuilder pour concatener les chaines puis retourner un nouveau string contenant la chaine résultant. Ca revient donc à l'exemple précédent.

    Pour conclure, c'est pour ca qu'il ne faut pas utiliser == en java mais plutot equals (à moins de savoir ce qu'on fait).

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2014
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2014
    Messages : 80
    Par défaut
    merci à tous.

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

Discussions similaires

  1. Passer des types primitifs par référence constante ?
    Par FluidBlow dans le forum Langage
    Réponses: 2
    Dernier message: 24/12/2010, 15h43
  2. Réponses: 11
    Dernier message: 21/05/2006, 14h39
  3. [info] passer d'un type primitif a String
    Par soad dans le forum Langage
    Réponses: 3
    Dernier message: 08/05/2005, 13h19
  4. [prog dynamique]Constructeur avec type primitif
    Par -=Spoon=- dans le forum Langage
    Réponses: 2
    Dernier message: 16/12/2004, 10h33
  5. Convertir un string en type property ou object
    Par bencot dans le forum Langage
    Réponses: 2
    Dernier message: 20/11/2004, 20h18

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