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 . |