String Pool-Verhalten

8

Ich lese diese Fragen zum Java-String-Pool und verstehe das grundlegende Konzept von String-Pool, aber verstehe immer noch nicht das Verhalten.

Erstens: Es funktioniert, wenn Sie den Wert direkt zuweisen und beide s1 und s2 beziehen sich auf das gleiche Objekt im Pool

%Vor%

Aber wenn ich dann die Zeichenfolge s1 +="d" ändere, sollte der Pool ein String-Objekt "abcd" haben? Wenn ich dann s2 +="d" ändere, sollte es das String-Objekt "abcd" im Pool finden und das Objekt s2 zuweisen? aber es ist nicht und sie sind nicht auf das gleiche Objekt bezogen. WARUM ist das?

%Vor%     
Jaxox 23.01.2013, 21:49
quelle

6 Antworten

7

Strings werden garantiert zusammengelegt, wenn Sie String.intern() für eine Zeichenfolge aufrufen.

%Vor%

Wenn der Compiler eine Konstante sieht, ist er schlau genug, um das String-Literal zu optimieren und zu bündeln, d. h .:

%Vor%

Java-Sprachspezifikation lautet:

  

Jedes Zeichenfolgenliteral ist eine Referenz   (§4.3) zu einer Instanz (§4.3.1, §12.5)   der Klasse String (§4.3.3). Zeichenfolge   Objekte haben einen konstanten Wert. Zeichenfolge   Literale - oder, allgemeiner gesagt, Strings   das sind die Werte der Konstante   Ausdrücke (§15.28) sind also "interniert"   um einzigartige Instanzen zu teilen, mit   die Methode String.intern.

Also, im Fall von s2 += "d" war der Compiler nicht so clever wie du und hast einfach "d" gepoolt.

    
Mirko Adari 23.01.2013 21:51
quelle
3

Da bin ich mir nicht sicher, das ist ziemlich spekulativ, aber ich vermute, dass es im ersten Beispiel einige Compiler-Tricks geben kann (wo es inline ist und ziemlich offensichtlich, was los ist), aber es ist nicht clever genug, um es im zweiten Beispiel (wo es nicht so offensichtlich ist) zu ziehen.

Wenn ich recht habe, sieht entweder der Compiler "a" + "bc" und komprimiert das einfach zur Kompilierzeit auf "abc" oder es sieht die zwei Zeilen und bündelt die Strings, weil es erkennt, dass sie benutzt werden. Ich wette auf den ehemaligen ..

Nicht alle Zeichenfolgen werden notwendigerweise zusammengeführt.

    
Jeff 23.01.2013 21:55
quelle
2

Siehe die Dokumentation für String # intern () . Die letzte Zeile dort besagt:

  

Alle Literalstrings und stringwertigen Konstantenausdrücke sind   interniert.

Ihr += -Beispiel ist weder eine Literalzeichenfolge noch ein Zeichenfolgenkonstantenausdruck und wird daher nicht in den String-Pool eingefügt.

    
GriffeyDog 23.01.2013 22:05
quelle
2

Der Compiler kann eine konstante Auswertung durchführen, aber nicht, wenn Sie die Werte ändern

Versuchen Sie stattdessen, zu folgen und zu sehen, was passiert, wenn Sie final von einer der Variablen ablegen.

%Vor%     
Peter Lawrey 23.01.2013 22:05
quelle
0

Das ist meine Vermutung:

String s1="a" + "bc"; String s2="ab" + "c";

Ich denke, das sind Kompilierzeiten, die bestimmt werden, um die gleiche Zeichenfolge zu erzeugen, und so wird nur ein Objekt für beide erstellt.

Aber wenn Sie "d" zu beiden hinzufügen, wird dies für beide Strings getrennt durchgeführt (da es in Echtzeit gemacht wird, könnte es Dinge wie Ausnahmen geben, die es unterbrechen usw., so dass es das nicht tun kann) und so wird nicht automatisch auf ein Objekt verwiesen.

    
Patashu 23.01.2013 21:55
quelle
0

Ich denke, was hier passiert ist: 1. für String s1="a" + "bc"; String s2="ab" + "c"; Der Java-Compiler ist intelligent genug, um zu wissen, dass der Literalwert von s1 und s2 gleich ist, sodass der Compiler sie auf den gleichen Literalwert im Stringpool

verweist
  1. für s1 +="d";
    s2 +="d";

Es gibt keine Möglichkeit, dass der Compiler weiß, ob s1 und s2 am Ende den gleichen Wert haben, Solange Sie String.intern () nicht aufrufen, überprüft jvm zur Laufzeit den String-Literal-Pool nicht, um festzustellen, ob der Wert bereits vorhanden ist.

    
seiya 23.01.2013 22:11
quelle

Tags und Links