Получить доступ

Что даёт неизменяемость (immutability) объекта?

JuniorООП
Ещё спрашивают так:
  • Зачем нужны неизменяемые объекты?
  • Как сделать класс неизменяемым?
  • Почему String неизменяемый?
Коротко

Неизменяемый объект потокобезопасен без синхронизации, безопасен как ключ Map / элемент Set и его можно свободно кэшировать и делить.

  • Как сделать: final-класс, private final поля, нет сеттеров, защитные копии изменяемых полей
  • record — быстрый способ, но копии вложенных коллекций всё равно на вас

А ещё Цена — новые объекты при каждом «изменении»

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

У неизменяемого (immutable) объекта наблюдаемое состояние не меняется после создания. Отсюда преимущества:

  • потокобезопасность — состояние нечем испортить гонкой, объект можно передавать между потоками без блокировок;
  • безопасность в хеш-коллекциях — хеш не изменится после добавления в HashMap или HashSet, объект не «потеряется»;
  • кэширование и переиспользование — один экземпляр можно отдавать всем (как String и пул строк);
  • простота рассуждений — объект нельзя изменить «снаружи» по ссылке.

Как сделать класс неизменяемым:

  1. запретить наследование (final класс или приватный конструктор);
  2. все поля private final;
  3. никаких сеттеров и методов, меняющих состояние;
  4. изменяемые поля (списки, даты старого API) копировать при создании и не отдавать наружу как есть — возвращать копию или неизменяемое представление.

Record даёт пункты 1–3 автоматически, но если поле — список, неизменяемость нужно обеспечить самому (List.copyOf). Цена подхода — «изменение» создаёт новый объект, поэтому для частых правок используют изменяемые билдеры (StringBuilder).

Пример

public record Order(long id, List<String> items) {
    public Order {
        items = List.copyOf(items); // защитная неизменяемая копия
    }
}

Что хотят услышать

  • Три выгоды: потокобезопасность, ключи коллекций, кэширование.
  • Как сделать класс неизменяемым, включая защитные копии.
  • Ограничение record с изменяемыми полями — плюс.

Частые ошибки

  • Связывать неизменяемость с хранением в стеке.
  • Думать, что она убирает NPE.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Потокобезопасность без синхронизации, безопасное использование как ключей Map / элементов Set и свободное кэширование и шаринг одного экземпляра
  • ✗Ускоряет любые операции, потому что объект хранится в стеке, а не в куче
  • ✗Автоматически уменьшает память, переиспользуя все объекты программы
  • ✗Гарантирует отсутствие NullPointerException

Что спросят дальше

  • Почему immutable безопасен как ключ HashMap?
  • Когда изменяемость всё же оправдана?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем