Навіщо використовувати Enums замість Constants? Що краще з точки зору дизайну програмного забезпечення та читабельності


77

У мене є сценарій , в якому у мене є типи гравця ARCHER , WARRIORі sorcerer.
Що слід використовувати в класі Player для типу гравця?
Постійна остаточна статична змінна рядка чи перелік ? і чому?
Будь ласка, допоможіть з причинами.


1
Я б не використовував змінну String. Якщо що, intзмінна (з приємно названими константами для різних типів).
Тіло

6
чи вам ця відповідь корисна? stackoverflow.com/questions/613837/…
Джиммі

можливий дублікат Чим корисний Enum?
oers


1
@RBz Це не змінює той факт, що перелічення в Java - це дуже різні звіри від переліку в C # та інших мовах, подібних до C. І навіть незважаючи на те, що він позначений мовно агностичним, відповіді на це питання є специфічними для C #.
Марк Роттевіл

Відповіді:


136

Припустимо, ви використовуєте константи (або intзначення - те саме стосується і них):

// Constants for player types
public static final String ARCHER = "Archer";
public static final String WARRIOR = "Warrior";

// Constants for genders
public static final String MALE = "Male";
public static final String FEMALE = "Female";

тоді ви в кінцевому підсумку не знаєте тип ваших даних - що призводить до потенційно неправильного коду:

String playerType = Constants.MALE;

Якщо ви використовуєте перелічення, це закінчиться як:

// Compile-time error - incompatible types!
PlayerType playerType = Gender.MALE;

Аналогічно, перелічення дають обмежений набір значень:

String playerType = "Fred"; // Hang on, that's not one we know about...

проти

PlayerType playerType = "Fred"; // Nope, that doesn't work. Bang!

Крім того, перелічення в Java можуть мати більше інформації, пов'язаної з ними, а також можуть мати поведінку. Набагато краще навколо.


4
А як щодо порівняння продуктивності між переліченнями та константами?
Вакас,

2
@ waqas716: Перерахування є еталонними типами, але на одне значення є лише один об'єкт, тому ви навряд чи витратите багато пам'яті. Якщо ви хочете інших відмінностей у продуктивності, вам слід сказати, що вас цікавить.
Джон Скіт,

1
Я повинен надіслати цей об’єкт Player до webService, тому я перетворюю цей об’єкт на Json String, у цьому випадку що я повинен використовувати константи рядків або Enum?
Вакас,

Ви завжди можете скористатися картою для переходу від Enums до Strings. (Також є двонаправлена ​​карта в Apache's Commons Collections 4, яка дозволяє переходити зі рядків до Enums, якщо це теж потрібно: commons.apache.org/proper/commons-collections/apidocs/org/… )
Jacob Holloway

13

Перелічення обмежують вас необхідним набором входів, тоді як навіть якщо ви використовуєте константи, ви все одно можете використовувати інший рядок, який не є частиною вашої логіки.

Це допомагає вам не помилитися, ввести щось поза доменом при введенні даних, а також покращує читабельність програми.

Крім того, ви завжди можете використовувати свої переліки як рядок, якщо хочете. Ось посилання .


6

Окрім того, що ви не дозволяєте вказати неправильне значення, є ще одна особливість перелічень, яка може здатися незначною, але, на мій погляд, досить важлива. Сучасні середовища розробки середовища можуть автоматично пропонувати значення для перерахувань, хоча немає можливості достовірно вивести можливі значення рядкової константи (Intellij IDEA робить останнє, але лише для класів JDK та популярних бібліотек). Це особливо корисно, коли ви досліджуєте новий API.


2

Enum краще використовувати для безпеки типу. Неможливо ввести неправильні значення. Але enum в android забирає стільки пам'яті, замість цього слід використовувати intdef. Зверніться до цієї відповіді для прикладу та пояснення: -

Приклад IntDef / StringDef

Ви також можете перевірити вихідний код Android, де він замінює перелічення IntDef / StringDef, де це можливо. Напр. Перегляд. ВИДИМИЙ.


0

Я порадив би вам використовувати перелічення, лише якщо вам дійсно потрібні перелічені константи або якась додаткова функціональність, загальна для всіх елементів.

Це, звичайно, залежить від типу програми, яку ви пишете, та яких версій та пристроїв ви хочете підтримувати.

Причина в тому, що перелічення додають накладні витрати, оскільки вони виділяють екземпляри своїх елементів. Ви можете помітити, що в платформі android є мінімальне перерахування, і майже всі константи є кінцевими статичними вставками (наприклад, View.GONE і подібні речі)


2
@ Джон Скіт: Що ви скажете з цього приводу?
Вакас,

1
Іноді безпека типу коштує витрат на "додаткові накладні витрати".
Michael Campbell
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.