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 неизменяемы и как добавить валидацию (если дошёл до 2-го слоя).