了解字符串文字池的示例

时间:2010-12-06 23:19:01

标签: java string string-literals

根据这篇文章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对象,而不是使用字符串文字池中的literalString1 literalString2

提前致谢

1 个答案:

答案 0 :(得分:1)

  

这是自新String(“someString”)以来的意外输出; JVM必须在运行时在堆上创建一个新的String对象

有义务创建一个新的String对象,是的。

但是,String对象通常只是一个包含几个字段的标题,以及一个指向后备数组的指针。 JVM可以自由地重用该后备阵列。

字符串应该是不可变的,如果你做的事情很费劲并且违反了不可变性,你就不能保证他们的行为方式。