


1. Предыстория появления enum
Сегодня мы изучим еще одну разновидность типов данных в Java — enum
. Название enum
происходит от слова Enumeration — перечисление. Что же это за тип данных и с чем его едят?
Иногда в работе программиста возникает необходимость создать новый тип данных, переменные которого принимают только значения из небольшого фиксированного списка.
Например, тип ДеньНедели
может принимать только значения ПОНЕДЕЛЬНИК
, ВТОРНИК
, СРЕДА
, ... Всего 7 значений. Или тип Месяц
может принимать только значения ЯНВАРЬ
, ФЕВРАЛЬ
, МАРТ
, ... Всего 12 значений.
Можно, конечно, использовать числа (тип int
): 1
— понедельник, 2
— вторник и т.д. Но кто-то случайно может присвоить такой переменной значение 8
, или, например, значение 0
.
Легко может возникнуть ситуация, когда один программист думает, что дни недели (или месяцы) нумеруются с нуля, другой — что с единицы и т.д.
Поэтому в Java придумали тип данных, который состоит из конечного набора значений — enum
.
2. Объявление типа
Выглядит объявление нового enum
типа данных так:
enum ИмяТипа
{
ЗНАЧЕНИЕ1,
ЗНАЧЕНИЕ2,
ЗНАЧЕНИЕ3
}
Где ИмяТипа
— это имя нового типа (класса), а в скобках через запятую перечислены возможные значения: Значение1
, Значение2
, Значение3
.
Давайте ради примера создадим свой enum
для типа ДеньНедели
:
Код | Примечание |
---|---|
|
Новый тип Day Понедельник Вторник Среда Четверг Пятница Суббота Воскресенье |
Присваивать значения переменным этого типа можно таким образом:
Day day = Day.MONDAY;
Пример:
Код | Примечание |
---|---|
|
На экран будет выведено:
|
3. Методы enum
’а
Тип enum
имеет несколько встроенных методов, два из них очень интересные:
Статический метод values()
возвращает массив всех значений типа enum
:
Код | Примечание |
---|---|
|
В переменную days сохраняется массив значений типа Day (7 штук)Выводим содержимое массива на экран:
|
Метод ordinal()
возвращает порядковый номер константы. Вызывать его нужно не у класса enum
, а у значения enum
:
Код | Вывод на экран |
---|---|
|
|
4. Преобразование в класс
На самом деле никакой магии тут нет, и компилятор просто подсыпал нам немного синтаксического сахара. Во время компиляции класс enum Day
будет преобразован в обычный класс:
Код, упрощенная версия | Примечание |
---|---|
|
Класс Day Список статических констант-значений Массив со всеми значениями типа Day Переменная со значением конкретного объекта Day private конструктор класса Day — объекты класса Day можно создавать только внутри класса Day .Метод ordinal нужно вызвать у объекта Day .Он возвращает значение объекта — value .Метод возвращает статический массив со всеми значениями класса Day |
Если убрать из класса Day
все статические методы и переменные, мы получим такую картину:
Код | Примечание |
---|---|
|
Переменная value хранит значение объекта Day Объекты Day можно создавать только внутри класса Day — конструктор private .Метод ordinal() возвращает значение value объекта Day .
|
Т.е. в принципе ничего страшного тут не происходит. Компилятор создает класс Day
, затем добавляет в него константы, которые были значениями у enum
, добавляет недостающие методы и делает конструктор класса private
. Как работают конструкторы, мы разберем немного позднее.
Теперь, думаем, понятно, почему мы заносим значение в переменную таким образом:
Day day = Day.MONDAY;
MONDAY
— это просто статическое поле (константа) класса Day
. А при обращении к статическим методам и полям извне класса перед именем поля или метода нужно указывать имя класса.
5. Еще методы enum
’а
Еще у всех enum
-классов есть несколько интересных особенностей.
Преобразование в строку и обратно
Чтобы преобразовать объект типа enum в строку, у него нужно вызвать метод toString()
.
String str = Day.MONDAY.toString();
Для обратного преобразования (строки в объект Day
) можно воспользоваться статическим методом valueOf()
:
Day day = Day.valueOf("MONDAY");
Очень удобно и полезно во многих случаях.
Преобразование в число и обратно
Как преобразовать объект типа enum
в число, вы уже знаете: для этого нужно вызвать метод ordinal()
:
int index = Day.MONDAY.ordinal();
Для обратного преобразования (числа в объект Day
) нужно воспользоваться конструкцией подлиннее:
Day day = Day.values()[2];
Примеры:
Код | Примечание |
---|---|
|
Понедельник Получаем индекс понедельника (0) День недели на 2 дня позже понедельника |
Важный момент, т.к. значения типа enum
представляют собой фиксированный набор констант, их можно сравнивать через ==. Ну не может существовать двух одинаковых объектов MONDAY
с разными ссылками. Каждый объект-значение типа enum существует только в единственном экземпляре. Поэтому сравнение переменных типа enum через == всегда будет работать.
6. Добавление своих методов в enum
Так как enum
во время компиляции превращается в обычный класс, в нем можно объявлять методы: эти методы просто добавятся в класс, который сгенерирует компилятор. Например, мы хотим, чтобы наш enum Day
возвращал не массив значений, а список.
Тогда в него можно дописать такой код:
Код | Примечание |
---|---|
|
После списка значений нужно поставить точку с запятой. Создаем объект ArrayList .Добавляем в него значения из массива: его возвращает метод values() .Возвращаем список. |
Теперь этот метод можно вызывать в коде:
Код | Примечание |
---|---|
|
В переменную list будет сохранен список всех значений enum ’а Day . |
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ