JavaRush /Курсы /JAVA 25 SELF /Перечисление: enum

Перечисление: enum

JAVA 25 SELF
10 уровень , 4 лекция
Открыта

1. Введение

В программировании часто приходится оперировать списками заранее известных, ограниченных вариантов. Например: дни недели, цвета светофора, уровни сложности игры, статусы заказа. Каждый из этих вариантов обычно представлен фиксированным значением. Вот тут мы и подбираемся ближе к нашей сегодняшней теме — перечислениям (enum).

Перечисление — это специальный тип данных, который позволяет объявлять набор именованных констант.

enum — как коробка с разложенными по ячейкам ярлыками, где каждый ярлык — уникальное имя, связанное с числом.

Главные плюсы enum:

  • Ваш код становится читаемым и самодокументируемым;
  • Вместо загадочных «магических чисел» вроде 0, 1, 2 появляются выразительные имена: DayOfWeek.MONDAY или TrafficLight.RED;
  • Компилятор будет ругаться, если вы попытаетесь присвоить некорректное значение;
  • За каждым элементом скрывается… обычное целое число! (Но к этому мы еще вернемся.)

Синтаксис объявления enum


// Общий шаблон объявления перечисления
public enum Имя
{
    КОНСТАНТА1 ,
    КОНСТАНТА2 ,
    КОНСТАНТА3
}
Синтаксис объявления перечисления enum

Объявить перечисление в Java очень просто. Вот базовый пример:

// Файл DayOfWeek.java
public enum DayOfWeek {
    MONDAY,			// 0	
    TUESDAY,		// 1
    WEDNESDAY,		// 2
    THURSDAY,		// 3
    FRIDAY,			// 4
    SATURDAY,		// 5
    SUNDAY			// 6
}

Пояснение:

  • Ключевое слово enum говорит компилятору: «Это перечисление!»
  • В фигурных скобках через запятую идут имена вариантов (констант).
  • Принято писать имена в UPPER_SNAKE_CASE (все буквы заглавные, слова через подчёркивание).

Где можно объявлять enum?

  • В отдельном файле (DayOfWeek.java).
  • Внутри класса (если нужно сделать приватное перечисление только для этого класса).
  • Даже внутри метода (но так делают редко).

2. Использование enum в коде

Объявление переменной enum:

DayOfWeek today = DayOfWeek.MONDAY;

Теперь today может принимать только одно из значений, объявленных в DayOfWeek.

Пример использования в switch

switch (today) 
{
    case MONDAY:
        System.out.println("Ох, понедельник...");
        break;
    case FRIDAY:
        System.out.println("Ура, пятница!");
        break;
    default:
        System.out.println("Обычный день.");
}

Важное отличие: в case пишем просто имя константы (без префикса), если тип переменной уже известен компилятору.

Перебор всех значений enum

У каждого enum есть статический метод values(), который возвращает массив всех его значений:

for (DayOfWeek day : DayOfWeek.values()) 
{
    System.out.println(day);
}

Это очень удобно для вывода меню, проверки, генерации вариантов и т.д.

3. Методы enum: name(), ordinal(), valueOf()

Перечисления в Java — не просто списки констант, а полноценные классы с методами!

Метод name()

Возвращает имя константы в виде строки (как оно написано в коде):

DayOfWeek day = DayOfWeek.FRIDAY;
System.out.println(day.name()); // "FRIDAY"

Метод ordinal()

Возвращает порядковый номер константы (счёт с нуля):

System.out.println(DayOfWeek.MONDAY.ordinal()); // 0
System.out.println(DayOfWeek.FRIDAY.ordinal()); // 4

Внимание: Не стоит хранить или сравнивать enum по ordinal(), если порядок может измениться в будущем! Лучше использовать имена.

Метод valueOf(String name)

Преобразует строку в значение enum, если такая константа существует:

DayOfWeek day = DayOfWeek.valueOf("MONDAY");
System.out.println(day); // MONDAY

Если строки не совпадают — будет выброшено исключение IllegalArgumentException.

Метод values()

Возвращает массив всех значений enum (уже был пример выше):

DayOfWeek[] days = DayOfWeek.values();

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

Перечисления в Java можно расширять: добавлять поля, конструкторы, методы! Да, это не просто список имён, а мини-класс.

Пример: дни недели с локализованным названием

public enum DayOfWeek 
{
    MONDAY("Понедельник"),
    TUESDAY("Вторник"),
    WEDNESDAY("Среда"),
    THURSDAY("Четверг"),
    FRIDAY("Пятница"),
    SATURDAY("Суббота"),
    SUNDAY("Воскресенье");

    private final String russianName;

    // Конструктор (private по умолчанию)
    DayOfWeek(String russianName) 
    {
        this.russianName = russianName;
    }

    public String getRussianName() 
    {
        return russianName;
    }
}

Подробнее как это работает вы узнаете, когда мы начнем изучать ООП в уровнях 27+ :P

Теперь можно делать вот так:

DayOfWeek day = DayOfWeek.WEDNESDAY;
System.out.println(day.getRussianName()); // "Среда"

Фишка: У каждого значения enum свои данные (в данном случае — русское название).

Преимущества использования enum

  • Безопасность типов: нельзя случайно присвоить переменной enum значение, которого нет в списке.
  • Читаемость: код сам себя документирует (TrafficLight.RED вместо 1 или "red").
  • Удобство поддержки: если нужно добавить или удалить вариант, делается это в одном месте.
  • Работает с switch: enum идеально подходит для ветвлений по значениям.
  • Можно расширять: добавлять поля, методы, реализовывать интерфейсы.
  • Меньше ошибок: компилятор поможет не забыть обработать варианты (особенно в switch-конструкциях).

6. Практика: используем enum в нашем приложении

Давайте добавим в наше мини-приложение поддержку дней недели через enum.

Шаг 1. Объявим enum

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

Шаг 2. Используем в коде

System.out.println("Введите день недели (например, MONDAY):"); 
Scanner console = new Scanner(System.in);                      
String input = console.nextLine().toUpperCase();               
                                                               
DayOfWeek day = DayOfWeek.valueOf(input);                      
switch (day) 
{                                                 
    case MONDAY:                                               
        System.out.println("Начало рабочей недели!");          
        break;                                                 
    case FRIDAY:                                               
        System.out.println("Скоро выходные!");                 
        break;                                                 
    case SATURDAY:                                             
    case SUNDAY:                                               
        System.out.println("Ура, выходные!");                  
        break;                                                 
    default:                                                   
        System.out.println("Обычный рабочий день.");           
}                                                              

Что происходит:

  • Пользователь вводит день недели (например, "monday" или "MONDAY").
  • Преобразуем строку к верхнему регистру (toUpperCase()), чтобы не зависеть от регистра.
  • Преобразуем строку в значение enum через valueOf.
  • Используем switch для вывода разного сообщения.
  • Если введено что-то не то — ловим ошибку и выводим предупреждение.

7. Типичные ошибки при работе с enum

Ошибка №1: Использование строк или чисел вместо enum. Очень часто начинающие программисты продолжают писать так:

int day = 1; // 1 — это понедельник?

или

String status = "DELIVERED";

Это плохо: можно ошибиться в написании, трудно поддерживать код. Используйте enum!

Ошибка №2: Сравнение enum через == и .equals(). В Java значения enum можно сравнивать через == — это безопасно, потому что все значения уникальны в рамках класса enum:

if (day == DayOfWeek.MONDAY) { ... } // ОК!

Хотя .equals() тоже работает, но чаще используют ==.

Ошибка №3: Плохие имена элементов enum. Не называйте элементы VALUE1, VALUE2, VALUE3 — через месяц никто не поймёт, что это значит! Используйте осмысленные имена.

Ошибка №4: Использование ordinal() для логики. Не пишите так:

if (day.ordinal() == 0) { ... } // Не надо!

Порядок элементов может измениться, и всё сломается. Используйте имена!

1
Задача
JAVA 25 SELF, 10 уровень, 4 лекция
Недоступна
Моделирование светофора 🚦
Моделирование светофора 🚦
1
Задача
JAVA 25 SELF, 10 уровень, 4 лекция
Недоступна
Сезонные поздравления в приложении 🌸☀️🍁❄️
Сезонные поздравления в приложении 🌸☀️🍁❄️
1
Задача
JAVA 25 SELF, 10 уровень, 4 лекция
Недоступна
Планирование недели в приложении 🗓️
Планирование недели в приложении 🗓️
1
Задача
JAVA 25 SELF, 10 уровень, 4 лекция
Недоступна
Навигация в космическом путешествии 🚀
Навигация в космическом путешествии 🚀
Комментарии (15)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
C0N5P1RACY Уровень 21
18 ноября 2025
Что то я вообще не понял зачем нужен enum, из всех примеров что тут приводились, я понял только то, что он только усложняет код. В примере "Практика: используем enum в нашем приложении" я вообще не вижу смысла в использовании enum, это все можно сделать намного проще и удобнее, enum тут только делает код нечитаемым, так что мне тяжело понять зачем существует вообще enum
Popka Уровень 24
25 декабря 2025
Потому что ты пока мыслишь слишком узко в рамках одной маленькой программы. А когда у тебя 3000 классов, тебе проще будет написать в своем коде Week.MONDAY, чем прописывать String week1 = "Monday"; Плюс откуда ты знаешь что ты прав, и значение может быть именно таким. Вдруг ты работаешь в странной компании где неделя начинается со среды. ENUM нужен не для локальных задач, он нужен для удобной и безопасной архитектуры большого проекта в будущем. Когда у тебя 100 папок проще в одном файле сделать enum, чем во всех этих 100 папках прописывать каждый раз одно и то же
C0N5P1RACY Уровень 21
25 декабря 2025
Да дело в другом было, просто лекции в этом новом курсе написаны как то.. Ну не особо понятно в общем На классическом курсе пару дней назад проходил enum, и в сравнении с лекцией тут (в новом), там (в старом) более понятно написано, от чего усваивается намного проще
Grrbrr7 Уровень 19
3 ноября 2025
Grrbrr7 Уровень 19
2 ноября 2025
В пункте 4 лекции переменная russianName которая final названа не по фэнь шую
Ловкий Лев Уровень 21
6 ноября 2025
static final - константа и всегда именуется в UPPER_SNAKE_CASE Что касается просто final (не static) Если переменная: локальная, или поле экземпляра - как russianName в данном случае, то она обычно именуется как обычная переменная - в camelCase.
FDX Уровень 47
10 октября 2025
в задаче "сезонные поздравления" валидатор счел фразу "Lorem ipsum dolor sit amet" не достаточно праздничной и заставил переписать :D
Ksanders Уровень 32
9 октября 2025
Уже который раз в лекциях создаются объекты класса, но так ни разу не было вменяемого объяснения зачем эти объекты вообще нужны. Сюда еще и конструктор приплели, зачем? Новички только путаются. При этом чтобы получить базовое понятия о структуре класса, конструкторе и объектах - надо ждать уровня 14 😡
Vitalii Уровень 32 Expert
5 октября 2025
/* Комментарий удален */
Ловкий Лев Уровень 21
6 ноября 2025
Если default идёт последним, break можно опустить - это допустимо и не влияет на выполнение программы. Его можно добавить туда только для единообразия и читаемости.
Vitalii Уровень 32 Expert
7 ноября 2025
Уже согласен. Тогда, что-то перепутал, так что удалю сообщение
Артемий Уровень 66
12 сентября 2025
Не понял, почему во всех задачах при объявлении enum не нужно указывать public
Big198801 Уровень 28
21 сентября 2025
так обычно не делают - тут даже не вложенный класс, а просто в одном файле для удобочитаемости закинули два класса, а в одном файле может быть только один public класс, и имя файла должно совпадать с именем public класса.
Alexandervmalysh Уровень 50
21 сентября 2025
Поддерживаю Gig198801. Даже IDEA предупреждает об этом и возникает ошибка компиляции:

Class 'DayOfWeek' is public, should be declared in a file named 'DayOfWeek.java'
C0N5P1RACY Уровень 21
18 ноября 2025
@Big198801 Бро ты лучший, единственный кто кратно и понятно объяснил почему