StringBuilder vs Verkettung in toString(): Wie es unter der Haube funktioniert

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

StringBuilder vs Verkettung in toString(): Wie es unter der Haube funktioniert

\n\n

Haben Sie sich jemals gefragt, warum auf Stack Overflow immer noch hitzig darüber diskutiert wird, wie man toString() in Java richtig schreibt? Manche Entwickler glauben fest daran, dass StringBuilder der einzig richtige Weg ist. Andere verwenden ganz entspannt die normale Verkettung mit Plus und machen sich keine Gedanken. Wer hat recht?

\n\n

Werfen wir einen Blick unter die Haube des Java-Compilers und des JIT (Just-In-Time)-Optimierers. Sie werden erfahren, was tatsächlich passiert, wenn Sie str1 + str2 schreiben und warum die Antwort auf diese Frage Sie im Jahr 2024 überraschen könnte.

\n\n

Warum ist dieses Thema so beliebt?

\n\n

Die Frage "StringBuilder vs String concatenation in toString()" hat auf Stack Overflow nicht ohne Grund tausende Aufrufe. Jeder Java-Entwickler hat mindestens einmal die Methode toString() geschrieben. Und jeder stand vor der Wahl: Schön mit Plus schreiben oder "richtig" mit StringBuilder.

\n\n

Der Mythos, dass die String-Verkettung in Java immer langsam sei, existiert seit über 20 Jahren. Und er war wahr... in der Ära von Java 1.4 und Java 5. Aber die Compiler stehen nicht still.

\n\n

Was sagt die Java-Spezifikation?

\n\n

Laut der Java Language Specification (JLS §15.18.1) ist der +-Operator für Strings syntaktischer Zucker. Der Compiler ist verpflichtet, die String-Verkettung in effizienten Code umzuwandeln. Seit Java 5 (J2SE 5.0) ersetzt der javac-Compiler die Verkettung automatisch durch die Verwendung von StringBuilder.

\n\n

Überprüfen wir das in der Praxis.

\n\n

Beispielcode: Ein einfacher toString()

\n\n

Nehmen wir ein klassisches Beispiel – die Methode toString() für die Klasse 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

Sieht sauber und lesbar aus. Aber wie sieht das im Bytecode aus?

\n\n

Ein Blick in den Bytecode

\n\n

Kompilieren wir diese Klasse und schauen uns den Bytecode mit javap -c Person.class an:

\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

Sehen Sie? Der Compiler hat selbst einen StringBuilder erstellt! Er erzeugt ein neues StringBuilder-Objekt, ruft für jeden String-Teil append() auf und dann toString(). Das Gleiche, was Sie manuell geschrieben hätten, aber mit lesbarerem Quellcode.

\n\n

Und was ist mit explizitem StringBuilder?

\n\n

Schreiben wir nun eine Version mit explizitem StringBuilder:

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

Blogs

Buchempfehlungen