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 :

Comparaison 2 String avec ==


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2013
    Messages : 7
    Par défaut Comparaison 2 String avec ==
    Bonjour,

    On m'a toujours dit qu'il ne faut pas comparer 2 String avec "==" parce que ça compare les adresses.

    Mais alors j'ai voulu tester et je tombe sur ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    String ok = "ok";
    String bonjour = "ok";
     
    if( ok == bonjour)
    {
        System.out.println("ici");
    }
    Il m'envoie le message "ici".

    Pourquoi ? Ce sont des adresses différentes.

    Merci d'avance.

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 096
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : R&D - Palefrenier programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 096
    Par défaut
    Citation Envoyé par Azhenot Voir le message
    ce sont des adresses différentes.
    Ha bon ? Comment le sais tu ?

    Je n'ai pas la réponse théorique, par contre en faisant 2 essai et en désassemblant le code j'ai remarqué que apparemment, les 2 strings ont la même adresses.

    Test avec 2 fois ok.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
        public static void main(String args[])
        {
            String ok = "ok";
        //    0    0:ldc1            #16  <String "ok">
        //    1    2:astore_1
            String bonjour = "ok";
        //    2    3:ldc1            #16  <String "ok">
        //    3    5:astore_2
            if(ok == bonjour)
        //*   4    6:aload_1
        //*   5    7:aload_2
        //*   6    8:if_acmpne       19
                System.out.println("ici");
        //    7   11:getstatic       #18  <Field PrintStream System.out>
        //    8   14:ldc1            #24  <String "ici">
        //    9   16:invokevirtual   #26  <Method void PrintStream.println(String)>
        //   10   19:return
        }
    Test avec Ok et Ok1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
            String ok = "ok";
        //    0    0:ldc1            #16  <String "ok">
        //    1    2:astore_1
            String bonjour = "ok1";
        //    2    3:ldc1            #18  <String "ok1">
        //    3    5:astore_2
            if(ok == bonjour)
        //*   4    6:aload_1
        //*   5    7:aload_2
        //*   6    8:if_acmpne       19
                System.out.println("ici");
        //    7   11:getstatic       #20  <Field PrintStream System.out>
        //    8   14:ldc1            #26  <String "ici">
        //    9   16:invokevirtual   #28  <Method void PrintStream.println(String)>
        //   10   19:return
    donc a mon avis le compilateur il regarde les string hardcodé et il "optimise" niveau mémoire j'imagine. Mais c'est mon avis par essais/erreur.

    Enfin sinon en gros, je pense que le compilo mets les 2 string dans une pool de string et il s'arrange pour pas avoir 2 fois le même string.

    Tu peux aussi faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    String ok = new String("ok");
    		String bonjour = new String("ok");
     
    		if( ok == bonjour)
    		{
    			System.out.println("ici");
    		}
    Et constaté que la le comportement à changé.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre habitué
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2013
    Messages : 7
    Par défaut
    Oh ok donc vous pensez que c'est pour optimiser la mémoire.

    C'est vrai que c'est pratique vu que l'on sait qu'un String est immuable.

    Et avec StringBuffer effectivement ca ne fonctionne pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    StringBuffer ok = new StringBuffer("ok");
    StringBuffer bonjour = new StringBuffer("ok");
     
    if( ok == bonjour)
    {
      System.out.println("ici");
    }
    Merci beaucoup !

  4. #4
    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,

    une belle synthèse et explication du principe... désolé si l'anglais n'est pas votre fort

    Mais en gros, la théorie est que java optimise pour des raisons de performances, comme de mémoire, la création des instances de String lorsqu'on utilise l'affectation par constante, en utilisant un pool. En plus en cas de création par concénation, un StringBuilder est utilisé en interne, mais la chaîne affectée au final sera obtenue par la méthode intern() de String, donc venant du pool.

    Ainsi, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	public static void main(String[] args) {
     
    		String s1 = "hello";
     
    		String s2 = "h" + "e" + "l" + "l" + "o";
     
    		System.out.println(s1==s2);
     
     
    	}
    affichera true

    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	public static void main(String[] args) {
     
    		String s1 = "hello";
     
    		String s2 = new String("hello");
     
    		System.out.println(s1==s2); 
    		System.out.println(s1==s2.intern());
     
    	}
    affichera :
    false
    true
    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.

  5. #5
    Rédacteur/Modérateur
    Avatar de Laurent.B
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2004
    Messages
    3 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2004
    Messages : 3 468
    Responsable FAQ Eclipse | Maintiens et développe un des logiciels destinés aux rédacteurs sur developpez.com
    Gardons toujours à l'esprit que le forum constitue une base documentaire, dont l'utilité et la qualité dépendent du soin apporté à nos questions et nos réponses. Soyons polis, précis (dans le titre et dans le corps des questions), concis, constructifs et faisons de notre mieux pour respecter la langue française et sa grammaire. Merci pour nous (les modérateurs) mais aussi et surtout, merci pour vous.
    Problème solutionné => je vais au bas de la page et je clique sur le bouton (qui suite à mise à jour du forum, a légèrement changé d'aspect).

  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 joel.drigo Voir le message
    Mais en gros, la théorie est que java optimise pour des raisons de performances, comme de mémoire, la création des instances de String lorsqu'on utilise l'affectation par constante, en utilisant un pool.
    En fait peu importe que ce soit pour affectation ou passage en paramètre. Autrement dit peu importe dans quelle expression elle apparaît.
    En Java, toute expression constante String vient d'un pool.

    Rappel de ce qu'est une constante. Une expression constante est une expression qui pourrait servir à définir une constante.

    Citation Envoyé par joel.drigo Voir le message
    En plus en cas de création par concénation, un StringBuilder est utilisé en interne, mais la chaîne affectée au final sera obtenue par la méthode intern() de String, donc venant du pool.
    Dans ce cas-là c'est le compilateur qui se charge de la concaténation. Peu importe qu'il le fasse avec un StringBuilder ou quoi. Au runtime, le programme ne sait pas qu'il y avait concaténation dans le code source.

    Citation Envoyé par Laurent.B Voir le message
    Je constate une erreur dans cette FAQ

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    String a = "coucou";
    String b = "coucou";
     
    a==b;
    /** FAUX, a et b sont des instances différentes de String.
     * Ce résultat est théorique, car certains compilateurs pourraient optimiser
     * le code pour ne créer qu'une seule instance mémoire
     */
    Cet exemple ne marche pas

    Edit : ou peut-être qu'il était valide avant jdk 1.4, je ne trouve pas la doc. Mais ça commence à dater sévère.

    a==b renverra toujours true et il n'y a rien de théorique, c'est imposé par Java.
    Ils se sont tous les deux fait assigner une constante String, ces constantes viennent donc du pool, elles n'ont pas le choix. Vu qu'elles contiennent la même chose, le pool donnera la même String pour les deux.

    Ce qui ne veut pas dire que faire a==b est une bonne idée. Il ne faut pas, parce qu'en général quand on compare des String on ne sait pas si elles viennent du pool ou pas. (Plus exactement, en général il y en a au moins une qui ne vient pas du pool.)
    L'exemple n'illustre pas bien.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. Comparaison Tableau de String avec un string
    Par halloumiali dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 19/03/2012, 14h21
  2. Comparaison de String avec jokers
    Par kitsune dans le forum Langage
    Réponses: 8
    Dernier message: 22/05/2006, 15h21
  3. [DEBUTANT]comparaison une ligne avec un STRing
    Par Battosaiii dans le forum Langage
    Réponses: 2
    Dernier message: 05/05/2005, 20h15
  4. Réponses: 2
    Dernier message: 29/03/2004, 13h44
  5. string avec Dev-C++ 4
    Par Shadow Blade dans le forum Dev-C++
    Réponses: 15
    Dernier message: 20/03/2003, 18h50

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