Die Unterschiede zwischen StringBuilder
und StringBuffer
in Java sind gut dokumentiert und wurden in StackOverflow aufgerufen.
Grundsätzlich ist StringBuilder
eine nicht synchronisierte Kopie von StringBuffer
, mit fast der gleichen Schnittstelle, da es als schneller Ersatz für StringBuffer
gedacht war. Ihre API ist praktisch identisch und sie sind tatsächlich Unterklassen der gleichen unzugänglichen abstrakten Klasse im aktuellen JDK.
Ich frage mich daher, warum sie nicht öffentlich verwandt sind. Wenn beide Klassen eine gemeinsame Schnittstelle implementieren oder sogar StringBuffer
als Unterklasse von StringBuilder
haben, wäre das sinnvoll, da für beide Klassen gemeinsamer Code existiert.
Warum also diese erzwungene Trennung? War es so, dass Programmierer nicht unbeabsichtigt thread-safe mit thread-unsafe-Code mischen? Oder war es nur eine Designaufsicht, die nun bis zum Ende der Ewigkeit vererbt wird?
BEARBEITEN:
Um es klarzustellen: Ich kann spekulieren , warum die Dinge so sind, aber ich hoffe auf konkrete Hinweise auf eine tatsächliche Entscheidung, z. während eines JSR-Prozesses. Alles, was ein Licht auf etwas wirft, was für mich eine Situation ist, die gelegentlich eine gewisse Schwierigkeit verursacht.
EDIT 2:
Die Tatsache, dass beide Klassen Appendable
implementiert haben, ist komplett ausgerutscht mein Verstand. Wahrscheinlich, weil diese spezielle Schnittstelle für die meisten Zwecke nutzlos ist - sie kann nur ein einzelnes Zeichen oder ein vorbereitetes Objekt anhängen, und das ist es. In den meisten Fällen ist es nicht sinnvoller als beide Klassen Unterklassen von Object
.
EDIT 3:
Nun, hier ist der Grund für genau diese Frage von einer halboffiziellen Quelle :
Auswertung durch das Bibliotheksteam:
StringBuffer und StringBuilder verwenden standardmäßig keine gemeinsame Verwendung öffentlicher Supertyp Sie sind nicht als Alternativen gedacht: Eine ist eine Fehler (StringBuffer), und der andere (StringBuilder) ist es Ersatz.
Es ist klar, dass das Fehlen eines gemeinsamen Supertyps in einigen Fällen die Geschwindigkeit des Internets verlangsamen kann erhoffte Migration von StringBuffer zu StringBuilder. Die Kehrseite Wenn wir einen gemeinsamen Supertyp hinzufügen, nehmen wir die Fehler unserer Vergangenheit und sie in einer öffentlichen Schnittstelle zu verankern, um mit uns für alle zu sein Zeit. Dies verlangsamt nicht nur die Migration: es entgleist es.
Ich habe keine JSR-Referenz, aber von meinem exp. unten sind die paar Gründe:
StringBuffer
als Unterklasse von StringBuilder
ist aus Leistungsgründen keine gute Idee . Um StringBuffer
threadsicher zu machen, müssen Sie jeden Aufruf in StringBuilder
maskieren, was viel Overhead ist.
Zusätzlich zum obigen Punkt können Sie weiter optimieren, wenn Sie direkten Zugriff auf die Interna einer Klasse haben , weshalb Java java.lang.concurrent
über java.util.Collections.synchronized*
apis hinzugefügt hat. Da direkter Zugriff mehr Optionen für die Optimierung gibt. Um diesen Punkt zu unterstützen Referenz aus dem IBM Blog
Ich füge zum ersten Punkt hinzu, ich nicht denke, dass dies eine Design-Übersicht ist, da beide Klassen final
sind, also definitiv nicht wollen, dass diese Klassen unterklassifiziert werden.
Bei den gleichen Schnittstellen implementieren beide Klassen die gleichen Schnittstellen, d. h. Serializable, Appendable, CharSequence
. So sind sie Drop-In-Ersatz. Die einzige Sache ist, dass sie nicht eine gemeinsame Schnittstelle, sondern drei gemeinsame Schnittstellen implementieren. Das macht Sinn, da es keine Notwendigkeit gibt, eine aufgeblähte Schnittstelle zu haben, die technisch die Summe der aktuellen Schnittstellen ist ( Serializable, Appendable, CharSequence
).
BEARBEITEN:
StringBuffer
und StringBuilder
sind, aber nicht in irgendeiner der implementierten Schnittstellen. Dies hat mehr mit Rückwärtskompatibilität zu tun. Sie möchten eine neue API hinzufügen, aber die Schnittstelle wird von vielen anderen Klassen verwendet, so dass das Ändern einer Schnittstelle möglicherweise nicht möglich ist. Das ist eine gut durchdachte Entscheidung, die Java-Leute getroffen haben könnten. Also werde ich nicht sagen, dass es ein Fehler ist. EDIT 2:
SEITENHINWEIS: Eine weitere zu beachtende Sache ist, dass StringBuffer
in 1.0 eingeführt wurde und StringBuilder
in 1.5. Also werden die Apis, die es in beiden Klassen gibt, aber nicht in Interfaces, später eingeführt und nicht zum Zeitpunkt der Erstellung dieser Klassen.
Sie implementieren beide tatsächlich Appendable
.
Ich stimme nicht zu, dass dies nutzlos ist. Meiner Erfahrung nach hat ein großer Teil der Verwendung von StringBuilder / StringBuffer nur mit Strings zu tun (die CharSequence
implementieren). Für den Rest können Sie String.valueOf
aufrufen, bevor Sie es übergeben.
Es wäre praktisch, wenn es eine andere Schnittstelle gäbe, die auch die anderen Methoden wie append(long)
hätte. Aber das ist nicht wichtig.
Es wäre vernünftig, eine gemeinsame Schnittstelle zu haben. Sie haben unterschiedliche Leistungs- und Threading-Eigenschaften, aber das ist gut und richtig für viele Schnittstellen im JDK.
Beispiel: CopyOnWriteArrayList
in einem Array -basierte threadsichere Liste (erstellt für jeden Schreibvorgang eine neue Liste), während LinkedList
ist eine nicht threadsichere verknüpfte Liste.
Tags und Links java design-patterns stringbuilder stringbuffer