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Змінна зі значенням певного об'єкта Dayprivate конструктор класу 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. |
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ