Ich spielte mit Strings herum, um sie besser zu verstehen, und ich bemerkte etwas, das ich nicht erklären konnte:
%Vor%Wie lautet die letzte Zeile? das bedeutet, dass sowohl str1 als auch str3 dieselbe Adresse im Speicher haben.
Ist dies eine Compiler-Optimierung, die schlau genug ist, um zu erkennen, dass beide String-Literale gleich sind ("was auch immer") und damit str1 und str3 demselben Objekt zugewiesen werden? Oder fehlt mir etwas in der zugrundeliegenden Mechanik von Strings?
Wie der Beitrag sagt:
Die Zuweisung von Zeichenfolgen ist, wie bei allen Objektzuweisungen, sowohl zeit- als auch speicherintensiv. Die JVM führt einige Tricks aus, während String-Literale instanziiert werden, um die Leistung zu erhöhen und den Speicheraufwand zu verringern. Um die Anzahl der in der JVM erstellten String-Objekte zu reduzieren, behält die String-Klasse einen String-Pool bei. Jedes Mal, wenn Ihr Code ein Zeichenfolgenliteral erstellt, prüft die JVM zuerst den Zeichenfolgenliteralpool. Wenn die Zeichenfolge bereits im Pool vorhanden ist, wird eine Referenz auf die Pool-Instanz zurückgegeben. Wenn die Zeichenfolge nicht im Pool vorhanden ist, wird ein neues String-Objekt instanziiert und anschließend in den Pool eingefügt.
Weil Java einen Pool einzigartiger interned
Wie das Dokument sagt:
public String intern()
Gibt eine kanonische Darstellung für die Zeichenfolgenobjekt Ein ursprünglich leerer String-String wird beibehalten privat durch die Klasse String.
Wenn die interne Methode aufgerufen wird, wenn der Pool bereits a enthält Zeichenfolge, die diesem String-Objekt entspricht, wie vom Gleichheitszeichen (Object) bestimmt Methode, dann wird die Zeichenfolge aus dem Pool zurückgegeben. Ansonsten, das Das String-Objekt wird zum Pool hinzugefügt und es wird ein Verweis auf diese Zeichenfolge erstellt Objekt wird zurückgegeben.
Daraus folgt, dass für zwei beliebige Strings s und t, s.intern () == t.intern () ist genau dann wahr, wenn s.equals (t) wahr ist.
Alle Literalstrings und stringwertigen Konstantenausdrücke sind interniert. String-Literale sind in §3.10.5 der Java-Sprache definiert Spezifikation
Rückgabe: Eine Zeichenfolge, die den gleichen Inhalt wie diese Zeichenfolge hat, aber ist garantiert aus einem Pool von einzigartigen Strings.
Wenn Sie das tun:
%Vor% Dann erstellen Sie explizit ein String
-Objekt über new
-Operator (und -Konstruktor).
In diesem Fall weisen Sie jedes Objekt auf einen anderen Speicherort hin.
Aber wenn du es tust:
%Vor%Dann haben Sie eine implizite Konstruktion. Zwei Zeichenfolgenliterale teilen denselben Speicher, wenn sie dieselben Werte haben, da Java den Speicher der gleichen Zeichenfolgen speichert! (Strings, die den gleichen Wert haben)
Der javac
-Compiler kombiniert String-Literale, die in einer bestimmten Klassendatei gleich sind.
Allerdings werden String-Literale zur Laufzeit mit dem gleichen Ansatz wie String.intern () kombiniert. Dies bedeutet, dass sogar Strings in verschiedene Klassen in verschiedenen Anwendungen (in der gleichen JVM, die das gleiche Objekt verwenden.