0

根据这篇文章ScjpTipLine-StringsLiterally我正在编写一些示例,例如:

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);
}

输出是预期的:

true
false
aaaaaaaaaa
aaaaaaaaaa
someString

但是如果您稍微更改上面的代码替换该行

char[] charValue = "someString".toCharArray();

char[] charValue = (char[]) stringValue.get(literalString1);

你得到

true
false
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa

这是一个意外的输出,因为new String("someString"); JVM 必须在运行时在堆上创建一个新的 String 对象,而不是使用字符串字面量池中的literalString1literalString2

提前致谢

4

1 回答 1

1

这是一个意外的输出,因为 new String("someString"); JVM 必须在运行时在堆上创建一个新的 String 对象

是的,必须创建一个新的 String 对象。

然而,一个 String 对象通常只是一个带有几个字段的标题和一个指向支持数组的指针。JVM 可以自由地重用该支持数组。

字符串应该是不可变的,如果你做了一些复杂的事情来试图违反这种不变性,你就无法保证它们的行为方式。

于 2010-12-06T23:22:05.007 回答