Почему String в Java неизменяемый?
Неизменяемость String даёт пул строк (литералы разделяются безопасно), кэш hashCode (строка — идеальный ключ HashMap), потокобезопасность без синхронизации и безопасность: проверенный путь к файлу или имя класса нельзя подменить после проверки.
- Любая «модификация» создаёт новый объект
- Конкатенация в цикле — StringBuilder
- Пароли хранят в char[], чтобы можно было затереть
А ещё Внутри — массив байт (компактные строки Java 9: Latin-1 или UTF-16)
Подробно
Почему это важно для языка:
- Пул строк. Литерал
"abc"в разных местах программы — один объект. Это возможно только потому, что никто не может его изменить. - Хеш-код вычисляется один раз и кэшируется в поле — повторные
hashCode()бесплатны. Ключ HashMap не может «уехать» после вставки. - Потокобезопасность. Строку можно передавать между потоками без синхронизации.
- Безопасность.
checkPermission(path); open(path)— если бы строку можно было поменять между вызовами, проверка была бы бессмысленной. То же для имён классов в загрузчиках, URL, параметров сети.
Как устроено: класс final, поле с данными private final byte[], ни один метод не меняет массив. substring, replace, toUpperCase возвращают новые строки.
Цена — новые объекты при каждой «правке». Конкатенация в цикле квадратична, поэтому StringBuilder. Компилятор сам превращает a + b + c в одно выражение (Java 9+: invokedynamic StringConcatFactory), но внутри цикла так не сделает.
Пароли хранят в char[]: строку нельзя затереть, и она может долго висеть в памяти и попасть в дамп.
Что хотят услышать
- Пул, кэш хеша, потокобезопасность, безопасность.
- Цена неизменяемости и StringBuilder.
Частые ошибки
- Думать, что методы String меняют строку на месте.
- Конкатенировать строки через + в цикле.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Чтобы строки можно было безопасно менять из разных потоков
- ✗Чтобы экономить память за счёт изменения строки на месте
- ✓Ради безопасности, пула строк и кэширования hashCode
- ✗Чтобы JIT мог хранить строки в стеке и не создавать их в куче
Что спросят дальше
- Что делает intern()?
- Чем StringBuilder отличается от StringBuffer?
Разбор темы
- Строки: неизменяемость, пул и StringBuilder
Почему String immutable, String pool и intern, конкатенация и StringBuilder, char/code points и compact strings.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.