ein Beispiel für Strings Wörtliche Pool Legendes
-
09-10-2019 - |
Frage
Laut diesem Artikel ScjpTipLine-StringsLiterally Ich war Codierung einige Beispiele wie:
public static void main(String[] args) {
String literalString1 = "someString";
String literalString2 = "someString";
String string1 = new String("someString");
System.out.println(literalString1 == literalString2);
System.out.println(literalString1 == string1);
try {
Field stringValue = String.class.getDeclaredField("value");
stringValue.setAccessible(true);
char[] charValue = "someString".toCharArray();
Arrays.fill(charValue, 'a');
stringValue.set(literalString1, charValue);
} catch (Exception e) {}
System.out.println(literalString1);
System.out.println(literalString2);
System.out.println(string1);
}
Der Ausgang wird die erwartete:
true
false
aaaaaaaaaa
aaaaaaaaaa
someString
aber wenn man oben Ersetzen der Linie leicht ändern Sie den Code
char[] charValue = "someString".toCharArray();
mit
char[] charValue = (char[]) stringValue.get(literalString1);
Sie erhalten
true
false
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa
, die seit dem new String ( „somestring“) eine unerwartete Ausgabe ist; die JVM ist verpflichtet, ein neues String-Objekt auf dem Heap zur Laufzeit zu erstellen, anstatt mit dem literalString1 und literalString2 aus dem Stringliteral Pool.
Vielen Dank im Voraus
Lösung
, die eine unerwartete Ausgabe, da der neuen String ( „somestring“); die JVM ist verpflichtet, ein neues String-Objekt auf dem Heap während der Laufzeit
zu erstellen
Es ist verpflichtet, ein neues String-Objekt zu erstellen, ja.
Allerdings ist ein String-Objekt ist in der Regel nur ein Header mit einigen Feldern, und ein Zeiger auf Array sichern. Und die JVM ist frei, dass die Träger Array wieder zu verwenden.
Strings sollen unveränderlich sein, wenn Sie knifflig Dinge tun, um zu versuchen und zu verletzen, dass die Unveränderlichkeit, Sie bekommen keine Garantien, wie sie gehen zu verhalten.