Статьи

Полный курс по языку Java — от установки JDK до многопоточности и HTTP-запросов

Enum и record

Страница 18 из 30 · 2026-10-25 · 4 мин чтения

Enum

Перечисление — набор именованных констант фиксированного типа.

public enum Day {    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}
public class Main {    public static void main(String[] args) {        Day today = Day.FRIDAY;        System.out.println(today);        System.out.println(today.name());        System.out.println(today.ordinal());        for (Day d : Day.values()) {            System.out.println(d);        }        Day parsed = Day.valueOf("SUNDAY");        System.out.println(parsed == Day.SUNDAY);        System.out.println(today.compareTo(Day.MONDAY));    }}

Константы enum сравнивают через ==. Метод valueOf бросает IllegalArgumentException, если такой константы нет.

Enum в switch

public class Main {    static boolean isWeekend(Day day) {        return switch (day) {            case SATURDAY, SUNDAY -> true;            default -> false;        };    }    public static void main(String[] args) {        System.out.println(isWeekend(Day.SUNDAY));        System.out.println(isWeekend(Day.MONDAY));    }}

Enum с полями, конструктором и методами

public enum Planet {    MERCURY(3.303e+23, 2.4397e6),    EARTH(5.976e+24, 6.37814e6),    JUPITER(1.9e+27, 7.1492e7);    private final double mass;    private final double radius;    Planet(double mass, double radius) {        this.mass = mass;        this.radius = radius;    }    public double surfaceGravity() {        return 6.67300E-11 * mass / (radius * radius);    }}
public class Main {    public static void main(String[] args) {        for (Planet p : Planet.values()) {            System.out.printf("%s: %.2f%n", p, p.surfaceGravity());        }    }}

Конструктор enum всегда приватный.

Enum с поведением

Каждая константа может переопределять метод:

public enum Operation {    ADD("+") {        @Override        public int apply(int a, int b) {            return a + b;        }    },    SUBTRACT("-") {        @Override        public int apply(int a, int b) {            return a - b;        }    },    MULTIPLY("*") {        @Override        public int apply(int a, int b) {            return a * b;        }    };    private final String symbol;    Operation(String symbol) {        this.symbol = symbol;    }    public String getSymbol() {        return symbol;    }    public abstract int apply(int a, int b);}
public class Main {    public static void main(String[] args) {        for (Operation op : Operation.values()) {            System.out.println("6 " + op.getSymbol() + " 3 = " + op.apply(6, 3));        }    }}

Так вместо цепочки if/switch поведение хранится прямо в константе.

Enum и интерфейсы

public interface Priced {    double price();}
public enum Coffee implements Priced {    ESPRESSO(2.5),    LATTE(3.5),    CAPPUCCINO(3.2);    private final double price;    Coffee(double price) {        this.price = price;    }    @Override    public double price() {        return price;    }}

EnumMap и EnumSet

Специализированные коллекции для enum, быстрые и компактные:

import java.util.EnumMap;import java.util.EnumSet;import java.util.Map;import java.util.Set;public class Main {    public static void main(String[] args) {        Map<Day, String> plan = new EnumMap<>(Day.class);        plan.put(Day.MONDAY, "Работа");        plan.put(Day.SATURDAY, "Отдых");        System.out.println(plan);        Set<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);        Set<Day> workdays = EnumSet.complementOf(weekend);        System.out.println(workdays);    }}

Record

Запись — компактный способ объявить неизменяемый класс-носитель данных (Java 16+).

public record Point(int x, int y) {}

Компилятор сам создает:

  • приватные final поля;
  • конструктор со всеми полями;
  • методы доступа x() и y();
  • equals, hashCode, toString.
public class Main {    public static void main(String[] args) {        Point p = new Point(3, 4);        System.out.println(p);        System.out.println(p.x() + " " + p.y());        System.out.println(p.equals(new Point(3, 4)));    }}

Вывод:

Point[x=3, y=4]3 4true

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

Для проверки и нормализации значений:

public record Range(int from, int to) {    public Range {        if (from > to) {            throw new IllegalArgumentException("from > to: " + from + " > " + to);        }    }    public int length() {        return to - from;    }    public static Range of(int from, int to) {        return new Range(from, to);    }}
public record Email(String value) {    public Email {        value = value.trim().toLowerCase();        if (!value.contains("@")) {            throw new IllegalArgumentException("Некорректный email: " + value);        }    }}

Ограничения record

  • нельзя наследовать от другого класса, но можно реализовывать интерфейсы;
  • нельзя объявлять поля экземпляра сверх компонентов;
  • запись неявно final;
  • можно добавлять методы и статические члены.
public interface HasArea {    double area();}
public record Rectangle(double width, double height) implements HasArea {    @Override    public double area() {        return width * height;    }}

Record и pattern matching

Деконструкция записей в switch и instanceof (Java 21):

public sealed interface Shape permits Circle, Square {}
public record Circle(double radius) implements Shape {}
public record Square(double side) implements Shape {}
public class Main {    static double area(Shape shape) {        return switch (shape) {            case Circle(double r) -> Math.PI * r * r;            case Square(double s) -> s * s;        };    }    public static void main(String[] args) {        System.out.printf("%.2f%n", area(new Circle(1)));        System.out.println(area(new Square(3)));    }}

Когда что использовать

  • enum — фиксированный набор значений, известный заранее: дни недели, статусы, типы операций.
  • record — простой неизменяемый объект данных: координаты, DTO, результат запроса.
  • class — когда нужны изменяемое состояние, наследование или сложное поведение.