Ich war kürzlich auf der Suche nach einem Job und der Prüfer stellte mir eine einfache Frage: „Was sind die Unterschiede zwischen StringBuffer und StringBuilder und was sind ihre Anwendungsszenarien?“ Die Antwort des Herausgebers wird unten mit allen geteilt Jeder kann in Zukunft lernen und auch ein gutes Vorbild sein.
Suchen Sie einfach bei Google und Sie werden die Antwort erhalten: Die Methoden und Funktionen in StringBuffer und StringBuilder sind völlig gleichwertig, aber die meisten Methoden in StringBuffer werden mit dem synchronisierten Schlüsselwort geändert, sodass sie thread- sind. sicher und StringBuilder weist diese Änderung nicht auf und kann als threadunsicher angesehen werden.
Um die obige Antwort besser zu verstehen, ist es praktischer, sich direkt die Quellcode-Implementierung von StringBuffer und StringBuilder anzusehen. Als Programmierer ist es richtig, „im Zweifelsfall auf den Quellcode zu schauen“. So kann ich verantwortungsbewusst sagen: Natürlich gibt es Bedingungen!
Bei der Implementierung von jdk erben sowohl StringBuffer als auch StringBuilder von AbstractStringBuilder. Sie können sich einen ungefähren Überblick über die Sicherheit und Nichtsicherheit von Multithreading verschaffen, indem Sie die Menge der synchronisierten Methoden vor sich sehen im StringBuffer.
Hier ist ein lockerer Vortrag über das Implementierungsprinzip von AbstractStringBuilder: Wir wissen, dass die Verwendung von StringBuffer nichts anderes ist, als die Effizienz der String-Verbindung in Java zu verbessern, denn wenn + direkt für die String-Verbindung verwendet wird, erstellt jvm Mehrere String-Objekte führen zu einem gewissen Overhead. AbstractStringBuilder verwendet ein char-Array, um die anzufügende Zeichenfolge zu speichern. Wenn die Länge der angehängten Zeichenfolge die aktuelle char-Array-Kapazität überschreitet, wird das char-Array dynamisch erweitert, d. h. um einen größeren Zeitraum wird erneut Speicherplatz zugewiesen und kopiert dann das aktuelle char-Array an einen neuen Speicherort. Da der Aufwand für die Neuzuweisung von Speicher und das Kopieren relativ hoch ist, müssen Sie jedes Mal, wenn Sie Speicherplatz erneut beantragen, einen größeren Speicherplatz beantragen aktueller Bedarf.
Als nächstes wollen wir etwas Spaß haben!
Einige Informationen wurden in Google veröffentlicht:
[
StringBuffer startete mit JDK 1.0
StringBuilder startete mit JDK 1.5
Ab JDK 1.5 Ursprünglich Die Verbindungsoperation (+) mit String-Variablen wird intern von der JVM mit
StringBuilder implementiert, während diese Operation zuvor mit StringBuffer implementiert wurde.
】
Schauen wir uns den Ausführungsprozess anhand eines einfachen Programms an:
Listing 1 Buffer.java
public class Buffer { public static void main(String[] args) { String s1 = "aaaaa"; String s2 = "bbbbb"; String r = null; int i = 3694; r = s1 + i + s2; for(int j=0;i<10;j++){ r+="23124"; } } }
Verwenden Sie den Befehl javap -c Buffer, um seine Bytecode-Implementierung anzuzeigen:
Listing 2 Buffer-Klassen-Bytecode
Listing 1 und entsprechend Listing 2 konvertieren , die ldc-Anweisung im Bytecode von Listing 2 lädt die Zeichenfolge „aaaaa“ aus dem Konstantenpool an die Spitze des Stapels, istore_1 speichert „aaaaa“ in Variable 1 und wie unten lädt sipush eine kurze Zeichenfolge Die Ganzzahlkonstante Der Wert (-32768~32767) wird an die Spitze des Stapels verschoben, hier ist die Konstante „3694“. Weitere Java-Befehlssätze finden Sie in einem anderen Artikel „Java-Befehlssatz“.
Lassen Sie uns direkt sehen, dass 13, 13~17 ein StringBuffer-Objekt neu erstellt und seine Initialisierungsmethode aufruft, 20~21 zuerst Variable 1 über aload_1 an die Spitze des Stapels schiebt, wie bereits erwähnt, wird Variable 1 abgelegt Oben auf dem Stapel befindet sich die String-Konstante „aaaaa“ und ruft dann über die Anweisung invokevirtual die Append-Methode von StringBuffer auf, um „aaaaa“ zusammenzufügen. Das Gleiche gilt für die folgenden 24 bis 30 Sekunden. Rufen Sie abschließend die toString-Funktion von StringBuffer bei 33 auf, um das String-Ergebnis zu erhalten und es über astore in Variable 3 zu speichern.
Einige Leute sagen vielleicht, nachdem sie das gesehen haben: „Da die JVM StringBuffer intern verwendet, um Strings zu verbinden, müssen wir StringBuffer nicht selbst verwenden, sondern einfach „+“ verwenden!“ Wirklich? Natürlich nicht. Wie das Sprichwort sagt: „Es gibt einen Grund für die Existenz.“ Schauen wir uns weiterhin den Bytecode an, der der nachfolgenden Schleife entspricht.
37~42 sind alle Vorbereitungen vor dem Eintritt in die for-Schleife. 37 und 38 sollen j auf 1 setzen. 44 Hier wird j mit 10 über if_icmpge verglichen, springe direkt zu 73 Das heißt, die Return-Anweisung verlässt die Funktion. Andernfalls tritt sie in die Schleife ein, was dem Bytecode 47 bis 66 entspricht. Hier müssen wir uns nur 47 bis 51 ansehen, um zu wissen, warum wir StringBuffer verwenden müssen, um die Zeichenfolgenverbindung im Code zu verarbeiten, da die JVM jedes Mal, wenn die Operation „+“ ausgeführt wird, ein neues StringBuffer-Objekt erstellen muss, um die Zeichenfolgenverbindung zu verarbeiten String-Verbindung Dies kann teuer sein, wenn viele String-Verkettungsvorgänge erforderlich sind.
Weitere Artikel zu den Prinzipien und Unterschieden zwischen Java – StringBuffer und StringBuilder finden Sie auf der chinesischen PHP-Website!