Запечатанные типы с record
Моделируйте закрытые иерархии
«Запечатанные типы с record» — бесплатный урок Java Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.
Запечатанные типы и записи
Запечатанные интерфейсы и записи идеально сочетаются. Запечатанный интерфейс определяет закрытый набор вариантов, а каждая запись представляет один конкретный неизменяемый вариант. Вместе они позволяют моделировать алгебраические типы данных.
Записи неявно являются конечными
Запись автоматически является final, поэтому она удовлетворяет правилу, согласно которому разрешённые подтипы должны быть final, sealed или non-sealed. Дополнительный модификатор не требуется.
Закрытая иерархия фигур
Представьте фигуры как записи, реализующие запечатанный интерфейс, причём каждая запись содержит собственные данные.
public class Main {
sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
public static void main(String[] args) {
Shape s = new Rectangle(3, 4);
System.out.println(s);
}
}Добавление поведения
Запечатанный интерфейс может объявлять методы, которые реализует каждая запись, обеспечивая полиморфизм в пределах закрытого набора.
public class Main {
sealed interface Shape permits Circle, Rectangle {
double area();
}
record Circle(double radius) implements Shape {
public double area() { return Math.PI * radius * radius; }
}
record Rectangle(double width, double height) implements Shape {
public double area() { return width * height; }
}
public static void main(String[] args) {
Shape s = new Circle(2);
System.out.printf("Area: %.2f%n", s.area());
}
}Автоматические равенство и toString
Записи автоматически создают equals, hashCode и toString. Две записи с одинаковыми компонентами считаются равными, что идеально подходит для моделирования значений.
public class Main {
sealed interface Shape permits Circle {}
record Circle(double radius) implements Shape {}
public static void main(String[] args) {
Circle a = new Circle(5);
Circle b = new Circle(5);
System.out.println(a.equals(b));
System.out.println(a);
}
}Моделирование результатов
Распространённый подход — запечатанный тип результата с записью успешного результата и записью ошибки вместо возвращаемых значений, допускающих отсутствие значения, или исключений для ожидаемых исходов.
public class Main {
sealed interface Result permits Ok, Err {}
record Ok(int value) implements Result {}
record Err(String message) implements Result {}
static Result parse(String s) {
try { return new Ok(Integer.parseInt(s)); }
catch (NumberFormatException e) { return new Err("bad number: " + s); }
}
public static void main(String[] args) {
System.out.println(parse("42"));
System.out.println(parse("oops"));
}
}Компактные конструкторы для проверки
Записи могут проверять входные данные в компактном конструкторе, сохраняя корректность каждого варианта уже при его создании.
public class Main {
sealed interface Shape permits Circle {}
record Circle(double radius) implements Shape {
Circle {
if (radius < 0) throw new IllegalArgumentException("radius must be >= 0");
}
}
public static void main(String[] args) {
try { new Circle(-1); }
catch (IllegalArgumentException e) { System.out.println(e.getMessage()); }
}
}Рекурсивные модели данных
Поскольку запись может ссылаться на запечатанный интерфейс, можно строить рекурсивные структуры, например деревья выражений или связанные списки.
public class Main {
sealed interface Expr permits Num, Add {}
record Num(int value) implements Expr {}
record Add(Expr left, Expr right) implements Expr {}
public static void main(String[] args) {
Expr e = new Add(new Num(1), new Add(new Num(2), new Num(3)));
System.out.println(e);
}
}Преимущества неизменяемости
Записи неизменяемы на поверхностном уровне, поэтому иерархию записей легко анализировать, безопасно передавать и удобно использовать в параллельном выполнении. Защитное копирование самих записей не требуется.
Сочетание с оператором выбора
Запечатанные записи особенно хорошо сочетаются с сопоставлением с образцами в операторе выбора switch: каждый вариант может разобрать запись, а компилятор проверяет, что учтены все варианты. Это рассматривается в курсе по образцам.
Вычисление по модели
Можно написать интерпретатор в виде метода, который обходит рекурсивное дерево записей.
public class Main {
sealed interface Expr permits Num, Add {}
record Num(int value) implements Expr {}
record Add(Expr left, Expr right) implements Expr {}
static int eval(Expr e) {
if (e instanceof Num n) return n.value();
Add a = (Add) e;
return eval(a.left()) + eval(a.right());
}
public static void main(String[] args) {
Expr e = new Add(new Num(4), new Add(new Num(5), new Num(6)));
System.out.println(eval(e));
}
}Быстрая проверка
Проверьте своё понимание запечатанных записей.
Итоги
Вы научились сочетать запечатанные типы с записями.
- Записи неявно являются конечными, поэтому подходят как разрешённые подтипы.
- Запечатанный интерфейс может объявлять общие методы.
- Записи автоматически обеспечивают равенство, хеширование и toString.
- Вместе они позволяют моделировать закрытые, неизменяемые и, возможно, рекурсивные данные.
Часто задаваемые вопросы
Урок «Запечатанные типы с record» бесплатный?
Да — полный текст урока «Запечатанные типы с record» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «Запечатанные типы с record»?
Моделируйте закрытые иерархии Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Запечатанные типы с record»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Объявление запечатанных типов
- Условие permits
- Запечатанные типы с record
- Полный switch по запечатанному типу