Понимание примера строкового литерального пула - PullRequest
0 голосов
/ 07 декабря 2010

Согласно этой статье 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 Ответ

1 голос
/ 07 декабря 2010

, что является неожиданным выводом после новой строки ("someString"); JVM обязана создать новый объект String в куче во время выполнения

Обязательно создать новый объект String, да.

Однако объект String обычно представляет собой просто заголовок с несколькими полями и указатель на вспомогательный массив. И JVM может свободно использовать этот резервный массив.

Строки должны быть неизменными, если вы делаете непослушные вещи, пытаясь нарушить эту неизменность, вы не получаете никаких гарантий относительно их поведения.

...