Ich habe Java String für eine Weile studiert. Die folgenden Fragen basieren auf den folgenden Beiträgen
Java String ist eine spezielle
Unveränderlichkeit von String in Java
Unveränderlichkeit: Nach der Unveränderlichkeit wurde die String-Klasse so konzipiert, dass die Werte im gemeinsamen Pool an anderen Stellen / Variablen wiederverwendet werden können. Dies gilt, wenn das
String
als erstellt wurdeString a = "Hello World!";
Allerdings, wenn ich String wie erstelleString b = new String("Hello World!");
Warum ist das auch unveränderlich? (oder ist es?). Da dies einen dedizierten Heap-Speicher hat, sollte ich dies ändern können, ohne andere Variablen zu beeinflussen. Gab es also einen anderen Grund, warumString
insgesamt als unveränderlich angesehen wird? Oder ist meine obige Annahme falsch?Das zweite, was ich fragen wollte, war über den gemeinsamen String-Pool . Wenn ich ein String-Objekt als erstelle
String c = "";
Wird im Pool ein leerer Eintrag erstellt?
Gibt es schon einen Beitrag dazu? Wenn ja, könnte jemand den Link teilen?
quelle
Antworten:
new String()
ist ein Ausdruck, der einString
... erzeugt, und aString
ist unveränderlich, egal wie es erzeugt wird.(Zu fragen, ob
new String()
veränderlich ist oder nicht, ist unsinnig. Es ist Programmcode, kein Wert. Aber ich gehe davon aus, dass Sie das nicht wirklich gemeint haben.)Ja; Das heißt, für die leere Zeichenfolge wird ein Eintrag erstellt. Es ist nichts Besonderes an einem leeren
String
.(Um pedantisch zu sein, wird der Pooleintrag für
""
lange vor der Ausführung Ihres Codes erstellt. Tatsächlich wird er erstellt, wenn Ihr Code geladen wird ... oder möglicherweise sogar früher.)Ja ist es. Die Unveränderlichkeit ist jedoch eine grundlegende Eigenschaft von String-Objekten. Alle
String
Objekte.Sie sehen, die
String
API bietet einfach keine Methoden zum Ändern von aString
. Also (abgesehen von einigen gefährlichen und dummen 1 Tricks mit Reflexion) können Sie a nicht mutierenString
.Der Hauptgrund dafür, dass Java
String
als unveränderliche Klasse konzipiert ist, ist die Einfachheit. Es erleichtert das Schreiben korrekter Programme und das Lesen / Begründen des Codes anderer Personen, wenn die Kernzeichenfolgenklasse eine unveränderliche Schnittstelle bietet.Ein wichtiger zweiter Grund ist, dass die Unveränderlichkeit von
String
grundlegende Auswirkungen auf das Java-Sicherheitsmodell hat. Aber ich glaube nicht, dass dies ein Treiber für das Design der Originalsprache war ... in Java 1.0 und früher.Nein, es ist grundlegender als das. Alle
String
Objekte sind einfach unveränderlich. Es ist keine komplizierte Argumentation für Sonderfälle erforderlich, um dies zu verstehen. Es ist nur >> <<.Wenn Sie für den Datensatz ein veränderbares "string-like" Objekt in Java möchten, können Sie
StringBuilder
oder verwendenStringBuffer
. Dies sind jedoch verschiedene Typen von String.1 - Der Grund, warum diese Tricks (IMO) gefährlich und dumm sind, besteht darin, dass sie sich auf die Werte von Zeichenfolgen auswirken, die möglicherweise von anderen Teilen Ihrer Anwendung über den Zeichenfolgenpool gemeinsam genutzt werden. Dies kann Chaos verursachen ... auf eine Weise, dass der nächste Typ, der Ihren Code verwaltet, kaum eine Chance hat, ihn aufzuspüren.
quelle
String ist unveränderlich, unabhängig davon, wie es instanziiert wird
1) Kurze Antwort ist ja ,
new String()
ist auch unveränderlich.Da jeder möglicher wandelbar Betrieb (wie
replace
,toLowerCase
etcetra) , dass Sie führen anString
die Original nicht beeinflussenString
Instanz und gibt Ihnen eine neue Instanz .Sie können dies in Javadoc überprüfen für
String
. Jedepublic
MethodeString
, die verfügbar gemacht wird, gibt eine neueString
Instanz zurück und ändert nicht die aktuelle Instanz, für die Sie die Methode aufgerufen haben.Dies ist in Multithread-Umgebungen sehr hilfreich, da Sie nicht jedes Mal über Veränderlichkeit nachdenken müssen ( jemand wird den Wert ändern ), wenn Sie die
String
Umgebung passieren oder teilen .String
kann leicht der am häufigsten verwendete Datentyp sein, daher haben die Designer uns alle gesegnet, nicht jedes Mal über Veränderlichkeit nachzudenken, und uns viel Schmerz erspart.Unveränderlichkeit erlaubt String-Pool oder Caching
Aufgrund der Unveränderlichkeitseigenschaft war der interne String-Pool möglich. Wenn an einer anderen Stelle derselbe String-Wert erforderlich ist, wird diese unveränderliche Referenz zurückgegeben. Wenn
String
es veränderlich gewesen wäre, wäre es nicht möglich gewesen, solcheString
s zu teilen , um Speicherplatz zu sparen.Die Unveränderlichkeit von Strings war nicht auf das Pooling zurückzuführen, aber die Unveränderlichkeit hat mehr Vorteile.
String Interning oder Pooling ist ein Beispiel für ein Flyweight Design-Muster
2) Ja, es wird wie jedes andere interniert,
String
da ein Leerzeichen genauso wichtigString
istString
wie andereString
Instanzen.Verweise:
quelle
private
und keine der Methoden etwas ändert. Die Entscheidung,String
eine unveränderliche Klasse zu bilden, ist einfach eine Entwurfsentscheidung der Sprachdesigner und stellt keinen "besonderen" Teil der Kernsprache dar.Die Java-Bibliotheken sind stark auf die Einschränkung optimiert, dass jedes
String
Objekt unveränderlich ist, unabhängig davon, wie dieses Objekt aufgebaut ist. Selbst wenn Sie Ihreb
Verwendung erstellennew
, behandelt anderer Code, an den Sie diese Instanz übergeben, den Wert als unveränderlich. Dies ist ein Beispiel für das Wertobjektmuster, und alle Vorteile (Thread-Sicherheit, keine privaten Kopien erforderlich) gelten.Die leere Zeichenfolge
""
istString
wie alles andere ein legitimes Objekt, sie enthält einfach keinen internen Inhalt, und da alle Zeichenfolgen für die Konstante zur Kompilierungszeit interniert sind, kann ich praktisch garantieren, dass sie zur Laufzeitbibliothek bereits hinzugefügt wurde Schwimmbad.quelle
String
neuen 'String ()' einen dedizierten Eintrag im Heap macht, oder? Wie wird Unveränderlichkeit hier berücksichtigt, wenn dieser Speicher nirgendwo anders verwendet wird? Ich versuche nur zu verstehen, nicht unklug zu sein.new String()
unveränderlich ist, dann ist es einfach, weilString
es keine öffentlichen Methoden implementiert, um seinen Inhalt zu ändern Es gibt einfach keine Schnittstelle, über die man es ändern kann.1) Der unveränderliche Teil ist nicht wegen des Pools; es macht nur den Pool überhaupt erst möglich. Zeichenfolgen werden häufig als Argumente an andere Funktionen übergeben oder sogar mit anderen Threads geteilt. Strings unveränderlich zu machen war eine Designentscheidung, um das Denken in solchen Situationen zu vereinfachen. Also ja -
String
s in Java sind immer unveränderlich, egal , wie Sie sie erstellen (beachten Sie, dass es möglich ist wandelbar Strings in Java haben - nur nicht mit derString
Klasse).2) Ja. Wahrscheinlich. Ich bin mir nicht 100% sicher, aber das sollte der Fall sein.
quelle
Dies ist nicht unbedingt eine Antwort auf Ihre Frage, aber wenn hinter Ihrer Frage der Wunsch nach veränderlichen Zeichenfolgen steht, die Sie manipulieren können, sollten Sie die
StringBuilder
Klasse überprüfen , die viele der exakt gleichen Methoden implementiert,String
aber auch Methoden hinzufügt Ändern Sie den aktuellen Inhalt.Sobald Sie Ihre Zeichenfolge so erstellt haben, dass Sie damit zufrieden sind, rufen Sie sie einfach
toString()
auf, um sie in eine normale Zeichenfolge zu konvertierenString
, die Sie an Bibliotheksroutinen und andere Funktionen übergeben können, die nurString
s benötigen.Beides
StringBuilder
undString
implementiert dieCharSequence
Schnittstelle. Wenn Sie also Funktionen in Ihren eigenen Code schreiben möchten, die sowohl veränderbare als auch unveränderliche Zeichenfolgen verwenden können, können Sie diese alsCharSequence
Objekte deklarieren .quelle
Aus der Java Oracle-Dokumentation :
Und wieder:
Im Allgemeinen: "Alle primitiven" (oder verwandten) Objekte sind unveränderlich (bitte akzeptieren Sie meinen Mangel an Formalismus).
In Verbindung stehender Beitrag zum Stapelüberlauf:
Informationen zum Objektpool : Der Objektpool ist eine Java-Optimierung, die sich NICHT auf unveränderliche Daten bezieht.
quelle
Zeichenfolge ist unveränderlich bedeutet, dass Sie das Objekt selbst nicht ändern können, egal wie Sie es erstellt haben. Und was die zweite Frage betrifft: Ja, es wird ein Eintrag erstellt.
quelle
Eigentlich ist es umgekehrt.
Nein, die
String
Klasse ist unveränderlich, sodass Sie sicher auf eine Instanz verweisen können, ohne sich Sorgen machen zu müssen, dass sie von einem anderen Teil Ihres Programms geändert wird. Aus diesem Grund ist Pooling in erster Linie möglich.Betrachten Sie also Folgendes:
// this string literal is interned and referenced by 'a' String a = "Hello World!"; // creates a new instance by copying characters from 'a' String b = new String(a);
Was passiert nun, wenn Sie einfach einen Verweis auf Ihre neu erstellte
b
Variable erstellen ?// 'c' now points to the same instance as 'b' String c = b;
Stellen Sie sich vor, Sie übergeben
c
(oder genauer gesagt das Objekt, auf das verwiesen wird) eine Methode in einem anderen Thread und arbeiten weiterhin mit derselben Instanz in Ihrem Hauptthread. Und jetzt stellen Sie sich vor, was passieren würde, wenn Zeichenfolgen veränderlich wären.Warum ist das überhaupt so?
Nicht zuletzt deshalb, weil unveränderliche Objekte das Multithreading viel einfacher und in der Regel sogar noch schneller machen. Wenn Sie ein veränderbares Objekt (dh ein zustandsbehaftetes Objekt mit veränderlichen privaten / öffentlichen Feldern oder Eigenschaften) für verschiedene Threads freigeben, müssen Sie besonders darauf achten, dass der synchronisierte Zugriff (Mutexe, Semaphoren) gewährleistet ist. Trotzdem benötigen Sie besondere Sorgfalt, um die Atomizität bei all Ihren Operationen sicherzustellen. Multithreading ist schwer.
Beachten Sie in Bezug auf die Auswirkungen auf die Leistung, dass das Kopieren der gesamten Zeichenfolge in eine neue Instanz, um auch nur ein einzelnes Zeichen zu ändern, aufgrund von Synchronisationskonstrukten, die für einen threadsicheren Zugriff erforderlich sind, häufig schneller ist als das Auslösen eines teuren Kontextwechsels. Und wie Sie bereits erwähnt haben, bietet Unveränderlichkeit auch Internierungsmöglichkeiten, was bedeutet, dass die Speicherauslastung tatsächlich reduziert werden kann.
Es ist im Allgemeinen eine ziemlich gute Idee , so viel Material wie möglich unveränderlich zu machen .
quelle
1) Unveränderlichkeit: Die Zeichenfolge ist unveränderlich, wenn Sie sie aus Sicherheitsgründen auf neue oder andere Weise erstellen
2) Ja, es wird ein leerer Eintrag im String-Pool vorhanden sein.
Sie können das Konzept mithilfe des Codes besser verstehen
String s1 = new String("Test"); String s2 = new String("Test"); String s3 = "Test"; String s4 = "Test"; System.out.println(s1==s2);//false System.out.println(s1==s3);//false System.out.println(s2==s3);//false System.out.println(s4==s3);//true
Hoffe, dies wird Ihrer Anfrage helfen. Sie können den Quellcode für die String-Klasse jederzeit überprüfen, um das Verständnis zu verbessern. Link: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String .Java
quelle
1- String ist unveränderlich. Siehe Folgendes:
Ist eine Java-Zeichenfolge wirklich unveränderlich?
Sie können es also auf viele Arten erstellen.
2-Kurze Antwort: Ja wird leer sein.
quelle
Erstellte Zeichenfolgen sind immer unveränderlich, unabhängig davon, wie sie erstellt wurden.
Antworten auf Ihre Fragen:
Der einzige Unterschied ist:
Wenn eine Zeichenfolge wie folgt erstellt wird, wird
{String a = "Hello World!";}
nur ein Objekt erstellt.Und wenn es wie geschaffen ist -
{String b = new String("Hello World!");}
dann zwei Objekte erhalten erstellt. Das erste, weil Sie das Schlüsselwort 'new' verwendet haben , und das zweite wegen der String- Eigenschaft.Ja sicher. Es wird ein leerer Eintrag im Pool erstellt.
quelle
Der String ist unveränderlich, da er Ihnen keine Möglichkeit bietet, ihn zu ändern. Es ist so konzipiert, dass Manipulationen vermieden werden (es ist endgültig, das zugrunde liegende Array darf nicht berührt werden ...).
Ganzzahlig ist identisch, da es keine Möglichkeit gibt, sie zu ändern.
Es spielt keine Rolle, wie Sie es erstellen.
quelle
Unveränderlichkeit ist kein Merkmal von
new
, es ist ein Merkmal der KlasseString
. Es hat keine Mutator-Methoden, daher ist es unveränderlich.quelle
String A = "Test" String B = "Test"
Jetzt String
B called
"Test" .toUpperCase ()which change the same object into
"TEST", so
Einwill also be
"TEST" `, der nicht wünschenswert ist.quelle
Beachten Sie, dass in Ihrem Beispiel die Referenz geändert wird und nicht das Objekt, auf das sie verweist, dh dass
b
eine Referenz geändert werden kann und auf ein neues Objekt verweist. Dieses neue Objekt ist jedoch unveränderlich, was bedeutet, dass sein Inhalt "nach" dem Aufruf des Konstruktors nicht geändert wird.Sie können eine Zeichenfolge mit
b=b+"x";
oder ändernb=new String(b);
, und der Inhalt der Variablena
scheint sich zu ändern, aber verwechseln Sie nicht die Unveränderlichkeit einer Referenz (hier Variableb
) und des Objekts, auf das sie verweist (denken Sie an Zeiger in C). Das Objekt, auf das die Referenz zeigt, bleibt nach seiner Erstellung unverändert.Wenn Sie eine Zeichenfolge ändern müssen, indem Sie den Inhalt des Objekts ändern (anstatt die Referenz zu ändern), können Sie
StringBuffer
eine veränderbare Version von String verwenden.quelle