← Назад к вопросам

Где используется Enumeration?

2.3 Middle🔥 181 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Где используется Enumeration?

Краткий ответ

Enumeration (Enum) используется для определения фиксированного набора констант, которые не могут быть изменены во время выполнения программы. Это безопасный и типобезопасный способ работы с набором предопределённых значений.

Основные случаи использования

1. Статусы и состояния

public enum OrderStatus {
    PENDING,      // Ожидает обработки
    PROCESSING,   // В обработке
    SHIPPED,      // Отправлена
    DELIVERED,    // Доставлена
    CANCELLED;    // Отменена
}

public class Order {
    private Long id;
    private OrderStatus status;  // Тип-безопасно
    
    public void updateStatus(OrderStatus newStatus) {
        this.status = newStatus;
    }
}

Преимущества:

  • ✅ Не можем установить невалидный статус
  • ✅ IDE автодополнение
  • ✅ Switch statement работает идеально
  • ✅ Легко искать usage (grep, IDE refactor)

2. Направления и ориентация

public enum Direction {
    NORTH,
    SOUTH,
    EAST,
    WEST;
}

public class Coordinate {
    private int x, y;
    
    public void move(Direction direction, int distance) {
        switch (direction) {
            case NORTH -> y += distance;
            case SOUTH -> y -= distance;
            case EAST -> x += distance;
            case WEST -> x -= distance;
        }
    }
}

3. Роли и права доступа

public enum UserRole {
    ADMIN,
    MANAGER,
    USER,
    GUEST;
    
    public boolean canDelete() {
        return this == ADMIN || this == MANAGER;
    }
    
    public boolean canRead() {
        return true;  // Все могут читать
    }
}

public class User {
    private String name;
    private UserRole role;
    
    public boolean hasPermission(String action) {
        if (action.equals("delete")) {
            return role.canDelete();
        }
        return role.canRead();
    }
}

4. Типы платежей

public enum PaymentMethod {
    CREDIT_CARD,
    PAYPAL,
    BANK_TRANSFER,
    CRYPTO,
    GIFT_CARD;
}

public class Payment {
    private BigDecimal amount;
    private PaymentMethod method;
    
    public boolean isAvailable() {
        // Не все методы доступны везде
        return method != PaymentMethod.CRYPTO;  // Крипто недоступен
    }
}

Расширенное использование Enum

Enum с полями и методами

public enum Season {
    SPRING(90),      // Средняя температура
    SUMMER(25),
    AUTUMN(15),
    WINTER(0);
    
    private final int avgTemp;  // Каждый enum имеет значение
    
    Season(int avgTemp) {
        this.avgTemp = avgTemp;
    }
    
    public int getAverageTemperature() {
        return avgTemp;
    }
    
    public boolean isHot() {
        return avgTemp > 20;
    }
}

// Использование
Season summer = Season.SUMMER;
System.out.println(summer.getAverageTemperature());  // 25
System.out.println(summer.isHot());                   // true

Enum с комплексным поведением

public enum HttpMethod {
    GET(false),          // Не имеет body
    POST(true),          // Имеет body
    PUT(true),
    DELETE(false),
    PATCH(true);
    
    private final boolean hasBody;
    
    HttpMethod(boolean hasBody) {
        this.hasBody = hasBody;
    }
    
    public boolean hasRequestBody() {
        return hasBody;
    }
}

public class HttpRequest {
    private HttpMethod method;
    private String body;
    
    public boolean isValid() {
        if (!method.hasRequestBody() && body != null) {
            return false;  // GET не может иметь body
        }
        return true;
    }
}

Enum для операций

public enum Operation {
    ADD('+') {
        @Override
        public double apply(double x, double y) {
            return x + y;
        }
    },
    SUBTRACT('-') {
        @Override
        public double apply(double x, double y) {
            return x - y;
        }
    },
    MULTIPLY('*') {
        @Override
        public double apply(double x, double y) {
            return x * y;
        }
    },
    DIVIDE('/') {
        @Override
        public double apply(double x, double y) {
            if (y == 0) throw new ArithmeticException("Division by zero");
            return x / y;
        }
    };
    
    private final char symbol;
    
    Operation(char symbol) {
        this.symbol = symbol;
    }
    
    public abstract double apply(double x, double y);
    
    public static Operation of(char symbol) {
        for (Operation op : Operation.values()) {
            if (op.symbol == symbol) return op;
        }
        throw new IllegalArgumentException("Unknown: " + symbol);
    }
}

// Использование
Operation op = Operation.MULTIPLY;
System.out.println(op.apply(5, 3));  // 15

Enum в коллекциях

EnumSet и EnumMap

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

// EnumSet - оптимизирован для Enum, использует битовый массив
EnumSet<Day> weekdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);
EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);

weekdays.add(Day.MONDAY);
weekdays.contains(Day.FRIDAY);  // true
weekdays.remove(Day.WEDNESDAY);

// EnumMap - Map, оптимизированная для Enum ключей
EnumMap<UserRole, Integer> permissions = new EnumMap<>(UserRole.class);
permissions.put(UserRole.ADMIN, 100);
permissions.put(UserRole.USER, 10);
permissions.put(UserRole.GUEST, 1);

int adminPerms = permissions.get(UserRole.ADMIN);  // 100

Enum в базе данных

Сохранение Enum в БД

@Entity
@Table(name = "orders")
public class Order {
    @Id
    @GeneratedValue
    private Long id;
    
    // Сохранять как строку (более читаемо в БД)
    @Enumerated(EnumType.STRING)
    private OrderStatus status;
    
    // Или как число (более компактно)
    @Enumerated(EnumType.ORDINAL)
    private PaymentMethod method;
}

// В БД:
// status: 'PENDING' (STRING)
// method: 0 (ORDINAL - индекс в enum)

Сравнение Enum с другими подходами

Плохо: Использовать строки

// ❌ Неопасно - можем передать любую строку
public void updateStatus(String status) {
    // Что если передадут typo: "PENDDING"?
}

updateStatus("PENDING");   // OK
updateStatus("PENDDING");  // ошибка в runtime

Хорошо: Использовать Enum

// ✅ Типобезопасно - только валидные значения
public void updateStatus(OrderStatus status) {
    // Компилятор гарантирует валидное значение
}

updateStatus(OrderStatus.PENDING);     // OK
updateStatus("PENDING");               // Ошибка компиляции!

Практический пример: E-commerce

public enum PaymentStatus {
    PENDING("Ожидание платежа"),
    COMPLETED("Платёж завершён"),
    FAILED("Платёж не прошёл"),
    REFUNDED("Возврат");
    
    private final String description;
    
    PaymentStatus(String description) {
        this.description = description;
    }
    
    public String getDescription() {
        return description;
    }
    
    public boolean canRefund() {
        return this == COMPLETED || this == FAILED;
    }
}

public class Transaction {
    private BigDecimal amount;
    private PaymentStatus status;
    
    public void refund() {
        if (!status.canRefund()) {
            throw new IllegalStateException(
                "Cannot refund: " + status.getDescription()
            );
        }
        this.status = PaymentStatus.REFUNDED;
    }
}

Когда НЕ использовать Enum

// ❌ Не используй Enum для динамических значений
public enum User {  // Неправильно!
    JOHN, JANE, BOB;  // Это меняется в runtime
}

// ✅ Используй обычный класс
@Entity
public class User {
    private Long id;
    private String name;
}

Интеграция с JSON

public class OrderDTO {
    public Long id;
    
    @JsonProperty("status")
    public OrderStatus status;  // JSON: "PENDING" → OrderStatus.PENDING
}

// JSON:
// {"id": 123, "status": "PENDING"}
// Автоматически десериализуется в OrderStatus.PENDING

Выводы

Enum используется для:

  1. ✅ Фиксированных наборов значений (статусы, роли)
  2. ✅ Типобезопасности вместо строк
  3. ✅ Улучшения читаемости кода
  4. ✅ Полиморфизма (abstract методы в enum)
  5. ✅ Оптимизации (EnumSet, EnumMap)
  6. ✅ Явного списка допустимых значений

Enum - это один из самых важных паттернов в Java для работы с ограниченными наборами значений.

Где используется Enumeration? | PrepBro