Ответ
Неизменяемость класса String в Java — это фундаментальный дизайн-выбор, обеспечивающий безопасность, производительность и надежность.
Основные причины:
- Безопасность (Security): Строки часто хранят критичные данные (пароли, токены, пути к файлам). Если бы строка была изменяемой, переданная ссылка могла быть модифицирована получателем, что создает уязвимости.
- Потокобезопасность (Thread Safety): Неизменяемые объекты по своей природе потокобезопасны. Их можно свободно передавать между потоками без риска состояния гонки (race condition) и без необходимости синхронизации.
- Кэширование хэш-кода: Класс
Stringкэширует значение хэш-кода (hashCode) при первом вычислении. Поскольку строка не меняется, это значение гарантированно остается корректным, что резко ускоряет работу вHashMap,HashSetи других структурах, основанных на хэшах. - Оптимизация памяти (String Pool): JVM использует пул строк (String Pool) для хранения литералов. Если несколько переменных ссылаются на строку с одинаковым значением
"Hello", они указывают на один объект в пуле. Изменяемость разрушила бы эту оптимизацию.
Пример и демонстрация:
String s1 = "Hello"; // Помещается в String Pool
String s2 = "Hello"; // s2 получает ссылку на тот же объект из пула, что и s1
System.out.println(s1 == s2); // true (ссылки равны)
s1 = s1.concat(" World"); // Не изменяет исходный "Hello", а создает НОВУЮ строку "Hello World"
System.out.println(s1); // "Hello World"
System.out.println(s2); // "Hello" (оригинальная строка не тронута)
Для работы с изменяемыми последовательно символов следует использовать StringBuilder или StringBuffer.