Records (Java 16+)
Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy. Урок 51 из 87.
При создании простых классов, предназначенных для хранения данных, часто приходится писать повторяющийся шаблонный код: закрытые поля, конструктор, методы доступа, toString(), equals() и hashCode(). В Java 16 появились records, которые избавляют от этой рутинной работы.
record — это специальный класс, предназначенный для хранения неизменяемых данных. Его объявляют с помощью ключевого слова record, за которым следует список компонентов:
record Person(String name, int age) { }
// Эта единственная строка автоматически предоставляет:
// - private final поля: name и age
// - конструктор: Person(String name, int age)
// - методы доступа: name() и age()
// - toString(), equals() и hashCode()Использовать record просто:
Person p = new Person("Alice", 30);
System.out.println(p.name()); // Alice
System.out.println(p.age()); // 30
System.out.println(p); // Person[name=Alice, age=30]Обратите внимание, что accessor methods не используют префикс get: они просто называются так же, как fields. Records неявно являются final, поэтому их нельзя расширить. Все fields также являются final, что делает records по своей сути неизменяемыми.
Вы можете добавить custom methods и при необходимости переопределить автоматически сгенерированные methods. Также можно добавить проверку в compact constructor:
record Person(String name, int age) {
public Person {
if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
}
}Records идеально подходят для DTO, ответов API или любых сценариев, где нужен простой неизменяемый контейнер данных без написания шаблонного кода.
Задание
ЛегкоДавайте создадим систему бронирования билетов в кино, демонстрирующую элегантность записей Java. Вы увидите, как записи устраняют шаблонный код, но при этом позволяют добавлять custom методы и валидацию.
Вы организуете код в трёх файлах:
Movie.java: Create запись, представляющую фильм, с тремя компонентами:title(String),genre(String) иdurationMinutes(int). Add custom method с именемgetFormattedDuration(), которая возвращает duration в удобном формате:[hours]h [minutes]m(например, 142 минуты становятся2h 22m). Используйте целочисленное division и операцию modulo, чтобы вычислить hours и оставшиеся минуты.Ticket.java: Create запись, представляющую билет в кино, с тремя компонентами:movie(Movie),seatNumber(String) иprice(double). Add compact constructor, который проверяет price: если price меньше или равна нулю, выбросьтеIllegalArgumentExceptionс messagePrice must be positive. Также Add custom method с именемprintTicket(), которая возвращает многострочную строку:========== TICKET ========== Movie: [movie title] Genre: [movie genre] Duration: [formatted duration from movie] Seat: [seatNumber] Price: $[price] ============================Main.java: Объедините вашу систему бронирования! Вы получите пять inputs: название фильма (String), жанр (String), duration в минутах (int), номер места (String) и price билета (double).Create запись Movie с первыми тремя inputs, затем Create запись Ticket с фильмом, номером места и price. Выведите результат вызова
printTicket()для вашего билета.
Вы получите пять inputs по порядку: название фильма, жанр, duration (в минутах), номер места и price.
Обратите внимание, насколько записи чище по сравнению с традиционными классами: не нужно писать constructor, accessor, toString(), equals() или hashCode(). Compact constructor позволяет добавить валидацию без повторения присваиваний полям, а при необходимости вы всё ещё можете добавлять custom методы!
Попробуйте сами
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Считать входные данные
String title = scanner.nextLine();
String genre = scanner.nextLine();
int durationMinutes = Integer.parseInt(scanner.nextLine());
String seatNumber = scanner.nextLine();
double price = Double.parseDouble(scanner.nextLine());
// TODO: Создайте record Movie с title, genre и durationMinutes
// TODO: Создайте record Ticket с movie, seatNumber и price
// TODO: Выведите билет, используя метод printTicket()
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово thisМетодыПоля (атрибуты)Метод-конструкторПерегрузка конструкторовИтоги — Простой калькулятор4Наследование
Основы наследования (extends)Ключевое слово superПереопределение методов (@Override)Цепочка конструкторовКласс ObjectОдиночное и многоуровневое наследованиеПочему нет множественного наследования классовИтоги — Иерархия сотрудников7Специальные методы и класс Object
Метод toString()equals() и hashCode()Метод clone()compareTo() и ComparableИнтерфейс ComparatorПовторение — Кастомная сортировка2Модификаторы доступа и инкапсуляция
Обзор уровней доступаМетоды геттеры и сеттерыСокрытие данныхКлючевое слово finalИтоги — Менеджер банковского счета5Полиморфизм
Основы перегрузки методовПереопределение методов (Run-Time)Upcasting и DowncastingОператор instanceofАбстрактные классы и методыИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияАгрегация против композицииВнутренние, вложенные и анонимные классыEnums и методы перечисленийRecords (Java 16+)Sealed-классы (Java 17+)11Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy3Свойства класса и статические члены
Переменные экземпляра и статические переменныеСтатические методыСтатические блокиКонстанты (static final)Итоги: Счетчик и утилиты6Интерфейсы и абстрактные классы
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовDefault и Static методы в интерфейсахАбстрактные классы vs ИнтерфейсыФункциональные интерфейсыИтоги — Платежная система9Обобщения
Введение в обобщенияОбобщенные классыОбобщенные методыОграниченные параметры типаСимволы подстановки (Wildcards: ?, extends, super)Итоги — Обобщенный контейнер12Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»Паттерн «Итератор»Потренируйтесь самостоятельно: Онлайн-компилятор Java