StringBuilder vs concaténation dans toString() : comment ça fonctionne sous le capot

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

StringBuilder vs concaténation dans toString() : comment ça fonctionne sous le capot

\n\n

Vous êtes-vous déjà demandé pourquoi sur Stack Overflow les débats font encore rage sur la façon d'écrire correctement toString() en Java ? Certains développeurs croient fermement que StringBuilder est la seule voie correcte. D'autres utilisent tranquillement la concaténation simple avec le signe plus sans se prendre la tête. Qui a raison ?

\n\n

Regardons sous le capot du compilateur Java et de l'optimiseur JIT (Just-In-Time). Vous découvrirez ce qui se passe réellement lorsque vous écrivez str1 + str2 et pourquoi en 2024, la réponse à cette question pourrait vous surprendre.

\n\n

Pourquoi ce sujet est-il si populaire ?

\n\n

La question "StringBuilder vs String concatenation in toString()" a attiré des milliers de vues sur Stack Overflow pour une bonne raison. Chaque développeur Java a écrit au moins une fois la méthode toString(). Et chacun a été confronté au choix : écrire joliment avec le signe plus ou "correctement" avec StringBuilder.

\n\n

Le mythe selon lequel la concaténation de chaînes en Java est toujours lente existe depuis plus de 20 ans. Et il était vrai... à l'époque de Java 1.4 et Java 5. Mais les compilateurs n'ont pas cessé d'évoluer.

\n\n

Que dit la spécification Java ?

\n\n

Selon la spécification du langage Java (JLS §15.18.1), l'opérateur + pour les chaînes est du sucre syntaxique. Le compilateur est obligé de transformer la concaténation de chaînes en code efficace. Depuis Java 5 (J2SE 5.0), le compilateur javac remplace automatiquement la concaténation par l'utilisation de StringBuilder.

\n\n

Vérifions cela en pratique.

\n\n

Exemple de code : un toString() simple

\n\n

Prenons un exemple classique — la méthode toString() pour la classe Person :

\n\n
public class Person {\n    private String name;\n    private int age;\n    private String email;\n\n    @Override\n    public String toString() {\n        return "Person{" +\n                "name='" + name + '\\'' +\n                ", age=" + age +\n                ", email='" + email + '\\'' +\n                '}';\n    }\n}\n
\n\n

Cela semble propre et lisible. Mais à quoi cela ressemble-t-il en bytecode ?

\n\n

Regardons dans le bytecode

\n\n

Compilons cette classe et examinons le bytecode avec javap -c Person.class :

\n\n
public java.lang.String toString();\n    Code:\n       0: new           #7    // class java/lang/StringBuilder\n       3: dup\n       4: invokespecial #8    // Method StringBuilder."<init>":()V\n       7: ldc           #9    // String "Person{name='"\n       9: invokevirtual #10   // StringBuilder.append(String)\n      12: aload_0\n      13: getfield      #3    // Field name:Ljava/lang/String;\n      16: invokevirtual #10   // StringBuilder.append(String)\n      19: ldc           #11   // String "', age="\n      21: invokevirtual #10   // StringBuilder.append(String)\n      24: aload_0\n      25: getfield      #4    // Field age:I\n      28: invokevirtual #12   // StringBuilder.append(int)\n      31: ldc           #13   // String ", email='"\n      33: invokevirtual #10   // StringBuilder.append(String)\n      36: aload_0\n      37: getfield      #5    // Field email:Ljava/lang/String;\n      40: invokevirtual #10   // StringBuilder.append(String)\n      43: ldc           #14   // String "'}"\n      45: invokevirtual #10   // StringBuilder.append(String)\n      48: invokevirtual #15   // StringBuilder.toString():String\n      51: areturn\n
\n\n

Vous voyez ? Le compilateur a lui-même créé un StringBuilder ! Il crée un nouvel objet StringBuilder, appelle append() pour chaque partie de la chaîne, puis toString(). La même chose que ce que vous auriez écrit manuellement, mais avec un code source plus lisible.

\n\n

Et avec un StringBuilder explicite ?

\n\n

Écrivons maintenant une version avec un StringBuilder explicite :

\n\n
@Override\npublic String toString() {\n    Strin                

Blogs

Book Recommendations