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

Records: компактные носители данных

Что генерирует record, канонический и компактный конструкторы, ограничения и когда применять.

Что такое record

record (Java 16) — компактная форма неизменяемого носителя данных. Из объявления record Point(int x, int y) компилятор генерирует: private final поля-компоненты, канонический конструктор, аксессоры (x(), y() — без префикса get), а также equals/hashCode/toString строго по компонентам.

Это убирает горы шаблонного кода у DTO/value-объектов и делает их корректными по умолчанию (правильные equals/hashCode из коробки).

record Point(int x, int y) {}
// сгенерировано: поля, конструктор, x()/y(), equals/hashCode/toString

Канонический и компактный конструкторы

Канонический конструктор принимает все компоненты. Для валидации/нормализации удобен компактный конструктор — без списка параметров: в нём проверяют аргументы и при необходимости нормализуют их перед неявным присваиванием полей.

Можно добавлять и дополнительные конструкторы (они обязаны делегировать в канонический), статические фабрики и методы. Важная связка с неизменяемостью: record не делает защитных копий за вас — если компонент изменяемый (List, массив), его нужно скопировать в компактном конструкторе и при выдаче, иначе «неизменяемая» запись протекает.

record Period(LocalDate from, List<Event> events) {
    Period {                       // компактный конструктор
        if (from == null) throw new IllegalArgumentException("from");
        events = List.copyOf(events); // защитная копия изменяемого компонента
    }
}

Ограничения

record неявно final и не может наследовать класс (extends запрещён), но может реализовывать интерфейсы. Всё состояние задаётся компонентами — нельзя добавить произвольное instance-поле (только static).

Эти ограничения — следствие сути: record моделирует «прозрачный» агрегат данных, у которого идентичность определяется значениями компонентов, а не ссылкой.

Когда применять

Records идеальны для DTO, value-объектов, составных ключей Map, возврата нескольких значений из метода и как варианты в sealed-иерархиях для pattern matching.

Не подходят там, где нужна изменяемость или identity-семантика (JPA-сущности с жизненным циклом, объекты с поведением и инкапсулированным изменяемым состоянием) — для них обычный класс.

Как отвечать на собеседовании

Перечислите, что генерирует record (final-поля, конструктор, аксессоры без get, equals/hashCode/toString по компонентам), покажите компактный конструктор для валидации и обязательно — что record НЕ делает защитных копий (изменяемый компонент надо копировать сам). Назовите ограничения (final, нет extends, состояние только из компонентов) и уместные сценарии (DTO/value/ключи/варианты sealed).

Вопросы по теме

Читайте также

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

Знать тему — половина дела

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

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