Объясните механизм: почему объявление ссылочной переменной как final не делает объект неизменяемым?
final запрещает изменить значение самой переменной после инициализации, но не ограничивает состояние объекта, на который она ссылается. Поэтому ссылку нельзя переназначить, а вызываемые через неё методы всё ещё могут изменять объект.
В примере неизменной является связь переменной names с конкретным объектом списка, но содержимое списка остаётся изменяемым.
В объектно-ориентированном языке важно различать переменную, хранящую ссылку, и сам объект, расположенный в памяти. Такой подход позволяет отдельно зафиксировать привязку имени к объекту, не запрещая объекту поддерживать изменяемое состояние.
final решает задачу ограничения переназначения: компилятор проверяет, что переменная получила значение допустимое число раз и после этого не присваивается повторно. Это полезно для локальных переменных, полей и параметров, но само по себе не вводит глубокую неизменяемость объекта.
Ошибочное предположение, что final делает объект immutable, приводит к неверной оценке безопасности кода. Например, final-коллекция может изменяться через add, remove или другой метод, а final-поле может ссылаться на объект с изменяемыми вложенными полями.
Особенно опасна такая путаница в многопоточном коде. Запрет переназначения ссылки не обеспечивает автоматически потокобезопасность операций над объектом и не устраняет гонки данных.
Для ссылочного типа значение переменной — это ссылка на объект либо null. После инициализации final-переменной нельзя записать в неё другую ссылку или null, но вызов метода получает доступ к объекту и может изменить его внутреннее состояние.
Неизменяемость требует отдельного свойства самого класса: его состояние нельзя изменить после создания, поля обычно private final, отсутствуют изменяющие методы, а изменяемые компоненты защищаются копированием или заменяются неизменяемыми представлениями. Одного final на поле недостаточно, если поле хранит ссылку на изменяемый объект.
Для примитивной переменной final фиксируется само значение: число или логическое значение нельзя заменить. Для ссылочной переменной фиксируется только ссылка, поэтому нужно различать неизменность ссылки и неизменность объекта.
Есть и важное ограничение модели памяти Java. final-поля имеют специальные гарантии видимости после корректного завершения конструктора, но это не делает весь объектный граф неизменяемым и не заменяет безопасную публикацию объекта или синхронизацию изменяемого состояния.
Сервис хранит настройки в поле, объявленном как final, но передаёт наружу сам изменяемый объект настроек. Клиентский код не может заменить ссылку сервиса, однако может изменить настройки через полученный объект, что создаёт скрытый побочный эффект.
Рассматривались три варианта:
Выбран третий вариант: настройки создаются как неизменяемый объект и заменяются целиком при обновлении. final используется там, где ссылка должна оставаться постоянной, а неизменяемость обеспечивается контрактом и реализацией класса. В результате исключены случайные изменения через внешний код, а обновление стало явной операцией.
final для поля, что поле обязательно должно быть проинициализировано прямо при объявлении?Нет. final-поле можно инициализировать в конструкторе, а для статического final-поля — в статическом блоке, при условии что компилятор может доказать единственное присваивание на каждом допустимом пути инициализации. После завершения инициализации повторное присваивание запрещено.
final-параметр?Да. final у параметра запрещает только переназначить локальную переменную параметра внутри метода. Если параметр указывает на изменяемый объект, его методы могут изменить объект; кроме того, другие ссылки на тот же объект увидят это изменение.
final-поле объект безопасным для публикации между потоками?Не полностью. Для корректно завершённого конструктора Java предоставляет специальные гарантии видимости значений final-полей, но изменяемое состояние объекта и объекты, доступные через эти поля, требуют отдельного анализа. Для последующих изменений нужны неизменяемость, синхронизация, volatile-механизмы или другие средства безопасного обмена.