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 :

[Certification] Les strings et ==


Sujet :

Langage Java

  1. #1
    Membre éclairé
    Inscrit en
    Mars 2004
    Messages
    247
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 247
    Par défaut [Certification] Les strings et ==
    Bonjour, j'aimerais savoir si j'ai bien compris et si je peux considérer ce que je pense comme étant vrai.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    String a = "TEST";
    String b = "TEST";
    String c = new String("TEST");
    System.out.println(a=b); // affiche true;
    System.out.println(a.trim()=b.trim()); // affiche true;
    System.out.println(a.substring(0) == b.substring(0)); //affiche true;
    System.out.println(a.toLowerCase() == b.toLowerCase()); // affiche false;
    System.out.println(a==c); //affiche false;
    Donc toute String créer en utilisant = "TEST" sont identique, si l'on lui applique une fonction qui ne modifie pas la String elle reste identique. (exemple : trim si y a pas d'espace, substring si on prend toute la chaine, toUpperCase() si elle est deja en majuscule...)
    Par contre si je lui applique une fonction qui la modifie, un nouvel objet est créé et donc elle ne sont plus identique.
    Et avec un new String() le == ne fonctionne jamais.

    Est-ce que ce que j'ai mis est juste dans tout les cas?

  2. #2
    Membre Expert
    Avatar de natha
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 346
    Par défaut
    A part que c'est pas = mais == dans les 2 premiers tests, oui c'est juste normalement.

    De toute façon tu peux le tester toi même en compilant ce code...

  3. #3
    Membre éclairé Avatar de Chatbour
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    431
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 431
    Par défaut
    Salut à tous

    Pourquoi ça diffère lorsqu'on fait String c = new String("...") et non pas Strig c = "..." ?

    l'instruction String c = "..." n'appelle-t-elle pas implicitement le constructeur ?

  4. #4
    Membre Expert
    Avatar de natha
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 346
    Par défaut
    Non, quand il n'y a pas "new String()" ça ne crée pas de nouvelle instance, le compilo optimiser en ne créant qu'une instance de "TEST" et en l'utilisant partout où tu l'utilises.

  5. #5
    Membre éclairé Avatar de Chatbour
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    431
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 431
    Par défaut
    Citation Envoyé par natha Voir le message
    Non, quand il n'y a pas "new String()" ça ne crée pas de nouvelle instance, le compilo optimiser en ne créant qu'une instance de "TEST" et en l'utilisant partout où tu l'utilises.
    dans ce cas, la String c devient comme si il s'agissait d'une StringBuffer ?

  6. #6
    Membre éclairé
    Inscrit en
    Mars 2004
    Messages
    247
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 247
    Par défaut
    Oui désolé c'est bien ==, j'ai testé ce code et les résultats sont bons.

    Ce que je voulais être sur c'est que lorsque l'on applique une fonction sur 2 String == et que la fonction ne modifie pas les Strings elles restent ==.

    D'apres les tests que j'ai fait il me semble que c'est ça.

  7. #7
    Membre Expert
    Avatar de natha
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 346
    Par défaut
    Citation Envoyé par Chatbour Voir le message
    dans ce cas, la String c devient comme si il s'agissait d'une StringBuffer ?
    Ca c'est seulement si tu fais de la concaténation de chaîne ("toto" + "titi");

    Citation Envoyé par ganga Voir le message
    D'apres les tests que j'ai fait il me semble que c'est ça.
    C'est surtout écrit dans la javadoc des méthodes en question. Je ne sais pas s'il y a une règles à ça.

  8. #8
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Toutes les chaines de caractères déclaré dans un programme sont des constantes appelées des littérales, et "interné" par la JVM. C'est à dire qu'il n'y a qu'un seul et unique objet String en mémoire les représentant.

    Donc ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    String a = "TEST";
    String b = "TEST";
    String c = new String("TEST");
    On a un seul objet pour les 3 chaines "TEST". a et b pointent directement sur cet objet tandis qu'on crée un nouvel objet String en copie pour c.

    Donc on a deux objets identiques en mémoire, référencé par 3 variables.


    Les spécifications des String Literals présente bien le fonctionnement :
    • Deux String Literals identiques appartenant à la même classe ou au même package font référence au même objet String en mémoire. (d'où le a==b)



    On peut vérifier cela en affichant l'identityHashCode des références, qui est unique pour chaque objet en mémoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	System.out.println( "a = " + System.identityHashCode(a) );
    	System.out.println( "b = " + System.identityHashCode(b) );
    	System.out.println( "c = " + System.identityHashCode(c) );
    Ce qui donne chez moi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    a = 24052850
    b = 24052850
    c = 26022015
    On voit bien que a et b correspondent au même objet, et que c est bien distinct...



    Après pour les méthodes trim() et substring() elles sont optimisé de sorte à ne pas créer de nouveaux objets s'il n'y a aucune modification de faite (ce qui est le cas ici). Ce n'est explicitement dans la doc que pour trim() donc je ne suis pas sûr que ce comportement soient garantie dans tous les cas (cela peut donc varier selon l'implémentation de la classe String).



    Quand à la concaténation de chaine avec + elle peut se produire à deux niveaux :



    a++

  9. #9
    Membre Expert
    Avatar de natha
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 346
    Par défaut
    Merci pour la correction + précision Je n'ai été clair sur le coup du toto titi (en fait je ne suis pas sûr que j'étais au clair moi-même...).

    Ca m'arrange quand même que ça soit "tototiti" le comportement car j'ai beaucoup de requêtes SQL dans mon code qui sont codées comme suit :

    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
    19
    20
    21
    22
    	public static final String SELECTED_ATTRIBUTES_DIV_TUTORIAL =
    		" " + NOM_TABLE_DIV_TUTORIAL + ".DATE_CREATION," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".USER_CREATION," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".ELEMENT_CREATION," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".DATE_MUTATION," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".USER_MUTATION," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".STATUS," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".DB_ELEMENT_ID," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".ID," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".NOM," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".DESCRIPTION," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".GENTIL," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".DATE_JOUR," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".NOMBRE1," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".NOMBRE2," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".CODE," +
    		" " + NOM_TABLE_DIV_TUTORIAL + ".COPAIN_ID";
     
    	private static final String STMT_GET_DIV_TUTORIAL =
    		"SELECT " + SELECTED_ATTRIBUTES_DIV_TUTORIAL +
    		" FROM " + NOM_TABLE_DIV_TUTORIAL +
    		" WHERE ID = ?";
    C'est quand même mieux que chacune ne représente qu'une seule String et que ça ne fera pas de StringBuffer ou StringBuilder à l'exécution.

  10. #10
    Membre éclairé
    Inscrit en
    Mars 2004
    Messages
    247
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 247
    Par défaut
    Merci pour cette réponse très détaillé.

  11. #11
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par natha Voir le message
    C'est quand même mieux que chacune ne représente qu'une seule String et que ça ne fera pas de StringBuffer ou StringBuilder à l'exécution.
    Oui et c'est tout l'intérêt des constantes

    A ce propos une petite devinette avec ce code :
    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
    public class Main {
     
    	public static final String A = "HELLO";
    	public static final String B;
     
    	static {
    		B = "HELLO";
    	}
     
    	public static void main(String[] args) throws Exception {
     
    		System.out.println(A);
    		System.out.println(B);
    		System.out.println(A == B);
    	}
    }
    Qui affiche :
    On a donc bien affaire au même objet en mémoire, et pourtant il existe une certaine différence en A et B... Laquelle ?



    Pour info une différence similaire existe dans le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Main {
     
    	public static void main(String[] args) throws Exception {
     
    		final String A = "HELLO";
    		final String B;
    		B = "HELLO";
     
    		System.out.println(A);
    		System.out.println(B);
    		System.out.println(A == B);
    	}
    }

    a++

  12. #12
    Membre Expert
    Avatar de natha
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 346
    Par défaut
    J'imagine que la différence est au niveau du code compilé. A est directement remplacé partout par "HELLO" alors que B non.

    Vulgairement la classe est équivalente à :

    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
    public class Main {
     
    	public static final String B;
     
    	static {
    		B = "HELLO";
    	}
     
    	public static void main(String[] args) throws Exception {
     
    		System.out.println("HELLO");
    		System.out.println(B);
    		System.out.println("HELLO" == B);
    	}
    }
    C'est ça ?

  13. #13
    Membre éprouvé
    Avatar de Deadpool
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    1 312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 1 312
    Par défaut
    A est une constante et pas B?

    J'ai bon?

  14. #14
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par natha Voir le message
    A est directement remplacé partout par "HELLO" alors que B non.
    Citation Envoyé par Deadpool Voir le message
    A est une constante et pas B?
    Oui c'est exactement ca : A est une constante et est donc remplacé directement lors de la compilation par sa valeur.



    a++

  15. #15
    Membre averti

    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 19
    Par défaut
    == verifie uniquement que la valeur (pour les primitives) ou la référence (pour les objets) est la meme.

  16. #16
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 905
    Billets dans le blog
    54
    Par défaut
    Citation Envoyé par Chatbour Voir le message
    Salut à tous

    Pourquoi ça diffère lorsqu'on fait String c = new String("...") et non pas Strig c = "..." ?

    l'instruction String c = "..." n'appelle-t-elle pas implicitement le constructeur ?
    Comme indique par les autres, ce n'est pas exactement la meme chose qui est effectuee dans les deux cas. L'appel au constructeur est cependant relativement inutile dans la majorite des cas.

    Citation Envoyé par javadoc
    public String(String original)

    Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable
    Hum, souvenez vous quand meme que l'optimisation de la concatenation des String via StringBuilder ou StringBuffer est optionnelle et peut ne pas etre implementee suivant le fournisseur de votre compilateur :

    Citation Envoyé par http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.18.1
    An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

Discussions similaires

  1. Lecture de fichier : Probleme avec les string
    Par soda_o_rat dans le forum SL & STL
    Réponses: 10
    Dernier message: 11/08/2005, 22h59
  2. Realiser des tests exhaustifs sur les String
    Par Sarrus dans le forum Langage
    Réponses: 9
    Dernier message: 07/07/2005, 11h52
  3. Réponses: 4
    Dernier message: 10/03/2005, 14h10
  4. [Fichiers] BlockRead/Write et les Strings
    Par Clorish dans le forum Langage
    Réponses: 5
    Dernier message: 14/01/2005, 21h28
  5. probleme avec requete sql aime pas les strings
    Par lil_jam63 dans le forum Bases de données
    Réponses: 3
    Dernier message: 24/02/2004, 14h45

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