Карта / ООП / record для DTO

record для DTO

record — компактный способ объявить класс, который просто хранит данные. Часто такие классы называют DTO (Data Transfer Object) — они не содержат логики, только переносят данные из одного места в другое.

Без record пришлось бы писать класс с полями, конструктором, геттерами, equals, hashCode, toString — десятки строк. С record это одна строка:

record Point(int x, int y) {}

Point p = new Point(3, 4);
p.x();   // 3 — геттер сгенерирован автоматически
p.y();   // 4

Компилятор сам генерирует: конструктор, геттеры (x(), y() — без префикса get), equals(), hashCode(), toString(). Всё, что обычно пишется руками или генерируется IDE — здесь бесплатно.

Копнуть глубже

Поля record неизменяемы (immutable) — это намеренное ограничение. Нельзя изменить значение после создания, только создать новый объект:

Point p = new Point(3, 4);
p.x = 10;   // ❌ так не скомпилируется — нет даже сеттера

Можно добавлять собственные методы и валидацию в компактном конструкторе:

record Point(int x, int y) {
    Point {                          // компактный конструктор
        if (x < 0 || y < 0) throw new IllegalArgumentException("Координаты < 0");
    }
    double distanceFromOrigin() {    // обычный метод — можно
        return Math.sqrt(x * x + y * y);
    }
}
Под капотом

record — это всё ещё обычный класс в байт-коде, просто компилятор сам пишет за тебя весь шаблонный код (boilerplate). Под капотом он наследуется от java.lang.Record и помечен специальным атрибутом, который позволяет рефлексии и сериализации узнать состав полей.

Все поля record автоматически private final — отсюда и неизменяемость: final запрещает переприсвоить, а сеттеров компилятор просто не генерирует.

🎤 Закрыл тему, если можешь объяснить:
• зачем нужен `record` и что он генерирует автоматически;
• почему поля record неизменяемы и как добавить валидацию (если дошёл до 2-го слоя).