Когда строка (String) попадает в пул строк (String Pool) в Java?

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

Ответ

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

Строка попадает в пул в следующих случаях:

  1. При объявлении строкового литерала:

    String s1 = "Hello"; // "Hello" создается и помещается в пул (если его еще нет)
    String s2 = "Hello"; // s2 ссылается на тот же объект из пула
    System.out.println(s1 == s2); // true (одинаковые ссылки)
  2. При явном вызове метода intern():

    String s3 = new String("World"); // Создается новый объект в heap, вне пула
    String s4 = s3.intern(); // s4 ссылается на строку "World" из пула
    String s5 = "World"; // s5 также ссылается на объект из пула
    System.out.println(s4 == s5); // true
    System.out.println(s3 == s5); // false (разные объекты)
  3. При вычислении константного выражения на этапе компиляции:

    String s6 = "He" + "llo"; // Компилятор оптимизирует в "Hello" (конкатенация литералов)
    System.out.println(s1 == s6); // true ("Hello" уже в пуле)

Когда строка НЕ попадает в пул автоматически:

  • При создании через конструктор new String(...).
  • При конкатенации, где хотя бы один операнд — не константа (переменная или результат метода).
    String part = "He";
    String s7 = part + "llo"; // Создается новый объект в heap, не в пуле
    System.out.println(s1 == s7); // false

Почему это важно? Использование пула позволяет экономить память и ускорять сравнение строк через == (только для интернированных строк). Однако метод intern() следует использовать с осторожностью, так как пул находится в PermGen/Metaspace и может привести к утечке памяти, если интернировать слишком много уникальных строк.