Что такое string pool в Java и всегда ли строка создается в пуле
Что проверяют
Знаете ли вы, что в пул попадают не все строки, и понимаете ли следствия для сравнения.
Как отвечать
Пул строк это область, где хранится по одному экземпляру каждого строкового литерала. Строки неизменяемы, поэтому делить один объект между всеми безопасно, и это экономит память.
Нет, не все строки попадают в пул. Разбор по случаям:
- литерал попадает в пул. Два одинаковых литерала это один и тот же объект;
- конкатенация констант вычисляется на этапе компиляции, поэтому результат тоже литерал и тоже в пуле;
- создание через явное выделение объекта всегда создаёт новый объект вне пула, даже если такая строка там уже есть. Именно поэтому такая запись считается бессмысленной;
- конкатенация во время выполнения, результат чтения из файла, разбор ответа сервера дают новые объекты вне пула;
- явное помещение в пул отдельным методом возвращает ссылку на объект из пула, добавляя строку туда, если её не было.
Отсюда прямое следствие для сравнения: строки нельзя сравнивать оператором равенства. С литералами он случайно работает, потому что объект один, а с построенными во время выполнения перестаёт. Код проходит тесты и ломается на боевых данных.
Полезная историческая деталь: до седьмой версии пул жил в области постоянных объектов ограниченного размера, и его переполнение давало отдельную проблему. Начиная с седьмой он перенесён в обычную кучу, поэтому подчиняется общим правилам сборки мусора, а его размер настраивается.
Про ручное помещение в пул: приём существует, но применять его массово не стоит. Он экономит память при большом числе повторяющихся строк, но сам вызов не бесплатен и может стать узким местом.
Где спотыкаются
Сравнивают строки оператором равенства.
Создают строки явным выделением объекта.
Считают, что в пул попадает любая строка.
Не знают, что конкатенация констант вычисляется при компиляции.