JavaRush /Курсы /Java Multithreading /Enum, все особенности

Enum, все особенности

Java Multithreading
5 уровень , 1 лекция
Открыта
Enum, все особенности - 1

— Привет, Амиго!

— Привет, Билаабо!

— Я расскажу тебе об очень интересной штуке. Она довольно простая, но от этого становится еще интереснее. Эта штука называется enum. enum – это тип, заданный перечислением набора значений, которые могут принимать его переменные. Сразу пример:

Определение класса-enum
public enum Direction
{
 UP, DOWN, LEFT, RIGHT,
}
Использование enum’а
Direction direction = Direction.LEFT;

if (direction == Direction.LEFT)
 direction = Direction.RIGHT;
else 
 direction = Direction.DOWN;

— Т.е. мы просто перечисляем набор значений и все?

— Да, объявляем enum, внутри через запятую пишем его возможные значения.

Использовать его тоже довольно просто.

— А ему можно присваивать null?

— Да, enum – это обычный класс – вернее, одна из его разновидностей, таких как interface.

— Т.е. везде, где я могу использовать класс, я могу использовать enum?

— Да.

— А внутри класса можно объявить enum?

— Да.

— А унаследоваться от enum?

— Нет, ни наследоваться от enum, ни наследовать enum нельзя.

— А почему?

— Потому что Java-компилятор превращает enum примерно вот в это:

public final class Direction extends Enum
{
 public static final Direction UP = new Direction(); 
 public static final Direction DOWN = new Direction();
 public static final Direction LEFT = new Direction();
 public static final Direction RIGHT = new Direction();

 private Direction() {} //приватный конструктор
}

Как видно из этого примера:

1) Класс Direction обязательно наследуется от класса Enum, поэтому его нельзя унаследовать больше ни от чего.

2) Класс Direction объявлен final, поэтому от него нельзя ничего унаследовать.

3) Набор значений класса Direction на самом деле – это public static final переменные типа Direction. Что видно по коду их использования:

Direction direction = Direction.LEFT;

4) Класс Direction содержит только один конструктор и тот – приватный. Это значит, что объекты класса Direction можно создать только в коде внутри класса. Кроме объявленных объектов, других объектов создать нельзя.

5) Переменным типа Direction можно присвоить ссылку на любой из существующих объектов типа Direction – все они определены у него внутри. Других объектов данного типа нет, и не будет.

6) Объекты типа Direction можно сравнивать с помощью знака «==» — это будет просто сравнение ссылок.

— Не сказал бы, что все очень понятно, но после твоего примера, стало гораздо понятнее.

— Отлично. Тогда вот тебе еще чуток информации:

1) У каждого объекта типа Direction есть его уникальный номер. У первого (UP) – 0, у второго (DOWN) – 1, у третьего (LEFT) – 2, и т.д. Получить этот номер можно с помощью метода ordinal(). Внимание на экран:

Direction direction = Direction.LEFT;
int index = direction.ordinal();
int index2 = Direction.RIGHT.ordinal();

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

int leftIndex = Direction.LEFT.ordinal();

Direction[] array = Direction.values();
Direction left = array[leftIndex];

Т.е. мы можем у любого элемента enum’а получить его номер, а затем по номеру опять получить элемент.

Мы также можем использовать enum в цикле foreach:

for (Direction direction : Direction.values())
{
 System.out.println(direction);
}
Вывод на экран будет:
UP DOWN LEFT RIGHT

— Значит, у enum’а переопределен метод toString? Он же не выводит на экран что-то вроде
«com.javarush.Direction@123fd4»?

— Да, более того у каждого enum’а, а значит и у Direction есть возможность преобразовать его в строку и обратно.

Преобразование в строку:
String left = Direction.LEFT.toString(); // left == "LEFT";
Преобразование строки в enum:
Direction direction = Direction.valueOf("LEFT");

— О, все понятно.

А что будет, если в функцию valueOf передать строку, которой нет в Direction? Например, «AMIGO»?

— А ты сам как думаешь?

— Exception?

— Ага. IllegalArgumentException.

На этом наше введение в мир enum’ов окончено.

Комментарии (75)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Максим Li Уровень 44
26 ноября 2025
👓
I'll kick them all Уровень 5
22 августа 2025
Когда пришел в квест за многозадачностью. И половина квеста позади...
4el0vek3 Уровень 36
27 августа 2025
угу
Arslonbek Erkinov Уровень 38
15 июля 2024
минус ещё 25 материи 🙂
dim11981 Уровень 47
22 октября 2023
Можно к enum подмешать интерфейс:

public static void main(String[] args) {
        EnumMix e1 = OneTwoEnum.ONE;
        e1.show();
        System.out.println(e1.ordinal());
        // System.out.println(e1.name()); <-- не скомпилируется
        System.out.println(e1);
    }

    public interface EnumMix {
        void show();
        int ordinal();
    }

    public enum OneTwoEnum implements EnumMix {
        ONE, TWO;

        @Override
        public void show() {
            System.out.printf("%s,%s%n", ONE, TWO);
        }

        @Override
        public String toString() {
            return String.format("%s(%d)", name(), ordinal());
        }
    }
Zhenya Workout Уровень 43
30 января 2023
Почему у меня до этого раздела было 900 материи, а сейчас всего 40?
Кирилл Уровень 2
25 августа 2023
у меня такая же ситувция
27 июля 2025
2200 материи, вот куда её девать?
proxylunae Уровень 45
30 июля 2022
Видимо в конце курса будут лекции по System.out.println("Hello, world!"); 🙂
Ihor Prokudin Уровень 51
7 мая 2023
это лучше чем пред. большая задача
Алексей С Уровень 33
17 июня 2022
Я не понял. ordinal() и Direction.values() это не одно и тоже разве? Вроде оба возвращают индекс энума?
Anton Уровень 39
19 июня 2022
Нет, ordinal возвращает индекс элемента в массиве , a метод values возвращает сам массив
Anonymous #2725271 Уровень 49
28 апреля 2022
public static final Direction UP = new Direction(); public static final Direction DOWN = new Direction(); public static final Direction LEFT = new Direction(); Я щось не зрозумів, чи це поганий приклад? Тут виходить, що всі об'єкти однакові, а по факту мають мати різні значення value, які отримали через конструктор.
BobaFoba Уровень 28
25 мая 2022
value это ссылка на объект. UP, DOWN, LEFT, RIGHT - четыре разных объекта, у каждого своя ссылка, которую они получили при создании в конструкторе.

 public static final Direction UP = new Direction();
в этой строке объявляется и инициализируется переменная. тоесть выделяется область в памяти, создается ссылка на эту область (value), в эту область записывается значение (UP), а также номер (ordinal) зная одно из трех (ссылка/номер/значение), мы можем получить остальные два насколько я понимаю, все так
Рыбалко Иван Уровень 36
26 февраля 2022
стажировка Джавараш Если ссылка перестанет быть активной - напишите мне!
K. Уровень 39
18 января 2022
Немного непонятно "А что будет, если в функцию valueOf передать строку, которой нет в Direction? Например, «AMIGO»?". То есть мы не можем добавить новый объект в наш enum?
Vitaliy Уровень 41
25 января 2022
Программно нет. Все значения прописываются при объявлении.
K. Уровень 39
25 января 2022
спасибо!
BobaFoba Уровень 28
25 мая 2022
не можем потому что конструктор приватный