Что такое неизменяемость (immutable) строк в Java?

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

Ответ

Неизменяемость (immutable) означает, что объект класса String после создания не может быть изменен. Любая операция, которая кажется модификацией строки (например, concat(), substring(), toUpperCase()), на самом деле создает новый объект String.

Пример:

String original = "Hello";
String modified = original.concat(" World");

System.out.println(original); // Вывод: "Hello" (исходный объект не изменился)
System.out.println(modified); // Вывод: "Hello World" (создан новый объект)
System.out.println(original == modified); // false (это разные объекты в памяти)

Причины и преимущества неизменяемости:

  1. Безопасность: Строки можно безопасно передавать между методами и потоками без риска их неожиданного изменения.
  2. Кеширование хеша: Хеш-код строки (hashCode) вычисляется один раз при первом вызове и кешируется, что повышает производительность при использовании в HashMap или HashSet.
  3. Потокобезопасность: Не требуется синхронизация, так как состояние объекта не меняется.
  4. Возможность пула строк (String Pool): JVM хранит литералы и строки, полученные методом intern(), в специальной области памяти (String Pool), что позволяет повторно использовать объекты и экономить память.

Для работы с изменяемыми последовательностями символов следует использовать:

  • StringBuilder — для однопоточных сценариев (высокая производительность).
  • StringBuffer — для многопоточных сценариев (потокобезопасен, но медленнее).