Warum nehmen gleiche Java-Strings die gleiche Adresse an? [Duplikat]

8

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?

    
MohamedEzz 19.11.2012, 08:55
quelle

4 Antworten

5

Ссылка

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.

    
Felipe Fernández 19.11.2012, 09:00
quelle
7

Weil Java einen Pool einzigartiger interned Instanzen, und String-Literale werden in diesem Pool gespeichert. Dies bedeutet, dass das erste "was auch immer" String-Literal genau dasselbe String-Objekt ist wie das dritte "was auch immer" Literal.

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.

     
    
Parth 19.11.2012 08:59
quelle
2

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)

    
Maroun 19.11.2012 09:03
quelle
1

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.

    
Peter Lawrey 19.11.2012 09:03
quelle

Tags und Links