Как в Java присвоить строке значение из String Pool?

«Как в Java присвоить строке значение из String Pool?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

String Pool (пул строк) — это специальная область heap-памяти для хранения уникальных строковых литералов. Попасть в него можно двумя способами:

1. Использование строкового литерала (автоматически):

String s1 = "Hello"; // Строка "Hello" создается и помещается в пул.
String s2 = "Hello"; // JVM находит "Hello" в пуле и возвращает ту же ссылку.
System.out.println(s1 == s2); // true — ссылки равны.

2. Явный вызов метода intern():

String s3 = new String("Hello"); // Создается новый объект в heap, ВНЕ пула.
String s4 = "Hello";
System.out.println(s3 == s4); // false — разные объекты.

String s5 = s3.intern(); // Помещаем строку из s3 в пул (или находим существующую).
System.out.println(s5 == s4); // true — теперь ссылаются на один объект в пуле.

Как работает intern():

  1. JVM проверяет, есть ли строка с таким значением в пуле.
  2. Если есть — возвращает ссылку на нее.
  3. Если нет — добавляет эту строку в пул и возвращает ссылку на новую запись.

Практические соображения и предостережения:

  • Производительность: intern() может быть дорогой операцией, так как требует синхронизации для проверки пула. Не используйте ее для динамических строк в высоконагруженных участках кода.
  • Применение: Полезно для уменьшения памяти при большом количестве повторяющихся строковых объектов (например, при парсинге CSV/XML).
  • Важно: Строки, созданные с помощью конкатенации в runtime ("He" + "llo"), также могут быть интернированы, если компилятор сможет вычислить значение на этапе компиляции (тогда это литерал), иначе — нет.

Итог: Для гарантированного попадания в пул используйте литералы или метод intern(), но помните о его накладных расходах.