Как Java обрабатывает создание строки, идентичной уже существующей в пуле строк?

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

Ответ

Поведение зависит от способа создания строки:

  1. Создание строковым литералом: JVM проверяет String Pool (пул строк) и возвращает ссылку на существующий объект. Новый объект не создается.

    String s1 = "largeText"; // Строка "largeText" создается и помещается в пул.
    String s2 = "largeText"; // JVM находит "largeText" в пуле и возвращает ссылку на тот же объект, что и s1.
    System.out.println(s1 == s2); // true (ссылки идентичны)
  2. Создание через конструктор new String(): Всегда создается новый объект в куче (heap), даже если идентичная строка есть в пуле.

    String s3 = new String("largeText"); // Новый объект в куче.
    String s4 = new String("largeText"); // Еще один новый объект.
    System.out.println(s3 == s4); // false (разные объекты в куче)
    System.out.println(s3.equals(s4)); // true (содержимое одинаковое)
  3. Метод intern(): Позволяет вручную поместить строку в пул или получить ссылку на уже существующую там строку.

    String s5 = new String("largeText").intern(); // s5 будет указывать на строку из пула.
    System.out.println(s1 == s5); // true

Итог по памяти:

  • Литералы предотвращают дублирование.
  • new String() приводит к избыточному потреблению памяти для идентичных данных.
  • intern() можно использовать для оптимизации, но его стоит применять с осторожностью из-за потенциальных накладных расходов.