Kürzlich, als ich nach einem Job suchte, stellte mir der Prüfer eine einfache Frage: "Der Unterschied zwischen StringBuffer und StringBuilder, was sind ihre Anwendungsszenarien?" Die Antwort des Editors wird unten bei Ihnen weitergegeben, damit es für alle in Zukunft bequem sein kann, um eine Aufzeichnung zu machen.
Suchen Sie einfach nach dem Google Master und Sie werden die Antwort haben: StringBuffer entspricht vollständig den Methoden und Funktionen in StringBuilder. Ohne diese Änderung kann StringBuilder als Thread-Unsafe betrachtet werden.
Um die obige Antwort besser zu verstehen, ist es besser, direkt zu erkennen, dass die Quellcode -Implementierung von StringBuffer und StringBuilder realistischer ist. Als Programmierer ist "wenn Sie Fragen haben, schauen Sie sich den Quellcode an", ist der richtige Weg. Ich kann verantwortungsbewusst sagen, natürlich müssen Sie Bedingungen haben!
In der Implementierung von JDK werden sowohl StringBuffer als auch StringBuilder von AbstractStringBuilder geerbt. Für die Sicherheit und Nichtsicherheit des Multi-Threading werden Sie die synchronisierten Methoden in StringBuffer grob verstehen.
Hier werde ich kurz über das Implementierungsprinzip von AbstractStringBuilder sprechen: Wir wissen, dass die Verwendung von StringBuffer nichts weiter ist, als die Effizienz der String -Verbindung in Java zu verbessern, da JVM, wenn Sie direkt für die String -Verbindung verwendet werden, mehrere String -Objekte erstellt, die einen bestimmten Overhead verursachen. AbstractStringBuilder verwendet ein Char -Array, um die angehängte Zeichenfolge zu speichern. Das Char -Array hat eine anfängliche Größe. Wenn die Stringlänge der Append -Zeichenfolge die aktuelle Char -Array -Kapazität überschreitet, wird das Zeichen -Array dynamisch erweitert, dh wiederum einen größeren Speicherplatz anwendet und dann das aktuelle Char -Array an einen neuen Standort kopiert. Da der Overhead der Neuzuordnung des Speichers und des Kopierens relativ groß ist, ist jedes Mal, wenn Sie wieder auf den Speicherraum anwenden, in der Art und Weise, wie der Speicherplatz größer ist als der erforderliche Strom, was 2-mal beträgt.
Als nächstes viel Spaß!
Hier sind einige Informationen in Google:
【
StringBuffer begann mit JDK 1.0
StringBuilder begann mit JDK 1.5
Ab JDK 1.5 wird der Verbindungsvorgang (+) mit String -Variablen intern von JVM verwendet
StringBuilder ist implementiert und dieser Vorgang wurde mit StringBuffer implementiert.
】
Wir betrachten den Ausführungsprozess über ein einfaches Programm:
Listing 1 Buffer.java
public class buffer {public static void main (String [] args) {String s1 = "aaaaa"; String S2 = "BBBBBBB"; String r = null; int i = 3694; r = s1 + i + s2; für (int j = 0; i <10; j ++) {r+= "23124"; }}}Verwenden Sie den Befehl Javap -c -Puffer, um seine Bytecode -Implementierung anzuzeigen:
Listing 2 Puffer -Klasse -Bytecode auflisten
Die entsprechende Liste 1 und Liste 2, in der LDC -Anweisung in Liste 2 lädt die Zeichenfolge "AAAA" vom konstanten Pool bis zum oberen Rand des Stapels, und IStore_1 speichert "AAAAA" in Variable 1. Die folgenden ist dieselbe. Sipush drückt einen kurzen Ganzzahl konstanten Wert (-32768 ~ 32767) auf die Oberseite des Stapels. Hier ist die konstante "3694". Weitere Java -Anweisungssätze finden Sie in einem anderen Artikel "Java -Anweisungssatz".
Sehen wir uns direkt an, dass 13, 13 ~ 17 in einem StringBuffer -Objekt neu ist und seine Initialisierungsmethode aufrufen. 20 ~ 21 ist, zuerst Variable 1 auf die Oberseite des Stapels durch ALOAD_1 zu drücken. Wie bereits erwähnt, wird Variable 1 in die Zeichenfolge konstant "AAAAAA" eingebaut und rufen dann die Anhangmethode von StringBuffer durch den Anweisungen auf, um "AAAAA" zusammen zu spleißen. Die folgenden 24 ~ 30 sind gleich. Schließlich wird in 33 die ToString -Funktion von StringBuffer aufgerufen, um das String -Ergebnis zu erhalten und in Variable 3 über den Store zu speichern.
Wenn wir dies sehen, kann jemand sagen: "Da der JVM StringBuffer verwendet, um Zeichenfolgen zu verbinden, müssen wir StringBuffer nicht selbst verwenden. Verwenden Sie einfach" nur "Just!" Ist das wahr? 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 einige Vorbereitungen, bevor sie in die für die für die Schleife gelangen. 37, 38 Setzen Sie J auf 1. 44 Hier vergleicht If_ICMPGE J mit 10. Wenn J größer als 10 ist, springt es direkt auf 73, dh die Rückgabeanweisung verletzt die Funktion; Andernfalls tritt es in die Schleife ein, dh den Bytecode von 47 ~ 66. Hier müssen wir uns nur 47 bis 51 ansehen, um zu wissen, warum wir StringBuffer in unserem Code verwenden, um String -Verbindungen zu verarbeiten, da JVM jedes Mal, wenn wir den "+" -Operation ausführen, ein neues StringBuffer -Objekt zum Umgang mit String -Verbindungen hat, was sehr teuer ist, wenn viele String -Verbindungsvorgänge beteiligt sind.