Что такое перечисления и почему они полезны?

Сегодня я просматривал некоторые вопросы на этом сайте и нашел упоминание об использовании enum в шаблоне синглтона о предполагаемых преимуществах безопасности потоков для такого решения.

Я никогда не использовал enum и программирую на Java уже более пары лет. И, видимо, они сильно изменились. Теперь они даже полностью поддерживают ООП внутри себя.

Теперь, почему и для чего мне использовать enum в повседневном программировании?

Ответы

Ответ 1

Вы всегда должны использовать перечисления, когда переменная (особенно параметр метода) может принимать только один из небольшого набора возможных значений. Примерами могут быть такие, как константы типов (статус контракта: "постоянный", "темп", "ученик" ) или флаги ( "выполнить сейчас", "выполнить отсрочку исполнения" ).

Если вы используете перечисления вместо целых чисел (или строковых кодов), вы увеличиваете проверку времени компиляции и избегаете ошибок при передаче недопустимых констант, и вы документируете, какие значения являются законными для использования.

Кстати, чрезмерное использование перечислений может означать, что ваши методы слишком много (часто лучше иметь несколько отдельных методов, а не один метод, который принимает несколько флагов, которые изменяют его действие), но если вам нужно использовать флаги или тип коды, перечисления - это путь.

В качестве примера, что лучше?

/** Counts number of foobangs.
 * @param type Type of foobangs to count. Can be 1=green foobangs,
 * 2=wrinkled foobangs, 3=sweet foobangs, 0=all types.
 * @return number of foobangs of type
 */
public int countFoobangs(int type)

против

/** Types of foobangs. */
public enum FB_TYPE {
 GREEN, WRINKLED, SWEET, 
 /** special type for all types combined */
 ALL;
}

/** Counts number of foobangs.
 * @param type Type of foobangs to count
 * @return number of foobangs of type
 */
public int countFoobangs(FB_TYPE type)

Вызов метода вроде:

int sweetFoobangCount = countFoobangs(3);

затем становится:

int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET);

Во втором примере сразу же выясняется, какие типы разрешены, документы и реализация не могут выйти из синхронизации, и компилятор может обеспечить это. Кроме того, неправильный вызов типа

int sweetFoobangCount = countFoobangs(99);

больше не возможно.

Ответ 2

Зачем использовать любую функцию языка программирования? Причина, по которой у нас есть языки, - это

  • Программисты для эффективного и правильного выражения алгоритмов в форме могут использовать компьютеры.
  • Потребители понимают алгоритмы, которые другие писали и правильно вносили изменения.

Перечисления улучшают вероятность правильности и удобочитаемости без написания большого количества шаблонов. Если вы хотите написать шаблон, то вы можете "имитировать" перечисления:

public class Color {
    private Color() {} // Prevent others from making colors.
    public static final Color RED = new Color();
    public static final Color AMBER = new Color();
    public static final Color GREEN = new Color();
}

Теперь вы можете написать:

Color trafficLightColor = Color.RED;

Вышеупомянутый шаблон имеет тот же эффект, что и

public enum Color { RED, AMBER, GREEN };

Оба обеспечивают одинаковый уровень проверки справки от компилятора. Бойлер - это всего лишь типизация. Но сохранение большого количества ввода делает программиста более эффективным (см. 1), поэтому это стоит.

Стоит, по крайней мере, еще одна причина:

Операторы switch

Одна вещь, которую симуляция static final enum выше не дает вам, - это приятные случаи switch. Для типов перечисления коммутатор Java использует тип своей переменной для определения области перечислений, поэтому для enum Color выше вы просто должны сказать:

Color color = ... ;
switch (color) {
    case RED:
        ...
        break;
}

Обратите внимание, что это не Color.RED в случаях. Если вы не используете перечисление, единственный способ использования именных величин с switch - это что-то вроде:

public Class Color {
    public static final int RED = 0;
    public static final int AMBER = 1;
    public static final int GREEN = 2;
}

Но теперь переменная для сохранения цвета должна иметь тип int. Хорошая проверка компилятора перечисления и симуляция static final исчезла. Не нравится.

Компромисс заключается в использовании в моделировании скалярнозначного элемента:

public class Color {
    public static final int RED_TAG = 1;
    public static final int AMBER_TAG = 2;
    public static final int GREEN_TAG = 3;

    public final int tag;

    private Color(int tag) { this.tag = tag; } 
    public static final Color RED = new Color(RED_TAG);
    public static final Color AMBER = new Color(AMBER_TAG);
    public static final Color GREEN = new Color(GREEN_TAG);
}

Сейчас:

Color color = ... ;
switch (color.tag) {
    case Color.RED_TAG:
        ...
        break;
}

Но заметьте, еще больше шаблонов!

Использование перечисления в качестве одноэлементного

Из приведенного выше шаблона вы можете увидеть, почему перечисление предоставляет способ реализации синглета. Вместо написания:

public class SingletonClass {
    public static final void INSTANCE = new SingletonClass();
    private SingletonClass() {}

    // all the methods and instance data for the class here
}

а затем доступ к нему с помощью

SingletonClass.INSTANCE

можно просто сказать

public enum SingletonClass {
    INSTANCE;

    // all the methods and instance data for the class here
}

что дает нам то же самое. Мы можем уйти от этого, потому что перечисления Java реализованы как полные классы с небольшим синтаксическим сахаром, покрытым сверху. Это опять меньше шаблонов, но это неочевидно, если идиома вам не знакома. Мне также не нравится тот факт, что вы получаете различные функции перечисления, даже если они не имеют большого смысла для синглтона: ord и values и т.д. (На самом деле сложнее симуляция, где Color extends Integer, которая будет работать с коммутатором, но это настолько сложно, что это еще более ясно показывает, почему enum - лучшая идея.)

Безопасность потока

Безопасность потоков - потенциальная проблема только в том случае, когда одиночные игры создаются лениво без блокировки.

public class SingletonClass {
    private static SingletonClass INSTANCE;
    private SingletonClass() {}
    public SingletonClass getInstance() {
        if (INSTANCE == null) INSTANCE = new SingletonClass();
        return INSTANCE;
    }

    // all the methods and instance data for the class here
}

Если многие потоки звонят getInstance одновременно, а INSTANCE все еще null, любое количество экземпляров может быть создано. Это плохо. Единственное решение - добавить synchronized доступ для защиты переменной INSTANCE.

Однако код static final выше не имеет этой проблемы. Он создает экземпляр с нетерпением при загрузке класса. Синхронизация загрузки классов.

Синтаксис enum фактически ленив, потому что он не инициализируется до первого использования. Инициализация Java также синхронизирована, поэтому несколько потоков не могут инициализировать более одного экземпляра INSTANCE. Вы получаете лениво инициализированный синглтон с очень маленьким кодом. Единственный минус - довольно неясный синтаксис. Вам нужно знать идиому или понять, как работает загрузка и инициализация классов, чтобы узнать, что происходит.

Ответ 3

Помимо уже упомянутых вариантов использования, я часто нахожу перечисления полезными для реализации шаблона стратегии, следуя некоторым основным рекомендациям ООП:

  1. Наличие кода, в котором находятся данные (то есть внутри самого перечисления - или часто внутри констант перечисления, которые могут переопределять методы).
  2. Реализация интерфейса (или более), чтобы не связывать клиентский код с перечислением (который должен обеспечивать только набор реализаций по умолчанию).

Простейшим примером будет набор реализаций Comparator:

enum StringComparator implements Comparator<String> {
    NATURAL {
        @Override
        public int compare(String s1, String s2) {
            return s1.compareTo(s2);
        }
    },
    REVERSE {
        @Override
        public int compare(String s1, String s2) {
            return NATURAL.compare(s2, s1);
        }
    },
    LENGTH {
        @Override
        public int compare(String s1, String s2) {
            return new Integer(s1.length()).compareTo(s2.length());
        }
    };
}

Этот "шаблон" можно использовать в гораздо более сложных сценариях, широко используя все полезности, которые поставляются с перечислением: перебирая экземпляры, полагаясь на их неявный порядок, извлекая экземпляр по его имени, статические методы предоставляют правильный экземпляр для конкретного контекста и т.д. И все же у вас все это скрыто за интерфейсом, поэтому ваш код будет работать с пользовательскими реализациями без изменений на тот случай, если вы захотите что-то, что недоступно среди "опций по умолчанию".

Я видел, как это успешно применялось для моделирования концепции гранулярности времени (ежедневно, еженедельно и т.д.), Где вся логика была заключена в перечисление (выбор правильной гранулярности для данного временного диапазона, специфическое поведение, связанное с каждой гранулярностью как константа). методы и т.д.). И все же, Granularity, с точки Granularity сервисного уровня, была просто интерфейсом.

Ответ 4

Что-то, что никто из других ответов не затронул, что сделать перечисления особенно мощными - это способность методов шаблона. Методы могут быть частью базового перечисления и переопределяться каждым типом. И с поведением, связанным с перечислением, он часто устраняет необходимость создания if-else или операторов switch, поскольку это сообщение Мышление в четвертом выпуске Java, которое посвящает целую главу тема. Особенно освещаются примеры, связанные с игрой Rock, Paper, Scissors (например, RoShamBo) в качестве перечислений.

Ответ 5

Из Java документы -

Вы должны использовать типы перечисления в любое время, когда вы необходимо представить фиксированный набор константы. Это включает естественное перечисление типы, такие как планеты в нашей солнечной систем и наборов данных, где вы знаете все возможные значения при компиляции времени, например, выбор на меню, флаги командной строки и т.д.

Общим примером является замена класса набором частных статических конечных int-констант (в пределах разумного числа констант) с типом перечисления. В принципе, если вы думаете, что знаете все возможные значения "что-то" во время компиляции, вы можете представить это как тип перечисления. Перечисления обеспечивают читаемость и гибкость над классом с константами.

Несколько других преимуществ, которые я могу представить о типах перечислений. Они всегда являются одним из экземпляров определенного класса enum (отсюда и понятие использования перечислений в качестве Singleton). Еще одно преимущество заключается в том, что вы можете использовать перечисления как тип в операторе switch-case. Также вы можете использовать toString() в перечислении, чтобы напечатать их как читаемые строки.

Ответ 6

Почему и зачем мне использовать enum в повседневном программировании?

Вы можете использовать Enum для представления небольшого фиксированного набора констант или режима внутреннего класса, увеличивая читабельность. Кроме того, Enums может обеспечить определенную жесткость при использовании в параметрах метода. Они предлагают интересную возможность передачи информации конструктору, как в примере "Планеты" на сайте Oracle, и, как вы обнаружили, также позволяют простой способ создания одноэлементного шаблона.

Locale.setDefault(Locale.US): Locale.setDefault(Locale.US) читается лучше, чем Locale.setDefault(1) и обеспечивает использование фиксированного набора значений, отображаемых в IDE при добавлении . разделитель вместо всех целых чисел.

Ответ 7

Enum перечислять фиксированный набор значений, самодокументируемым образом.
Они делают ваш код более явным, а также менее подверженным ошибкам.

Почему бы не использовать String или int вместо Enum для констант?

  • Компилятор не допускает опечаток, ни значения из фиксированного set, поскольку перечисления типы сами по себе. Последствия:
    • Вам не нужно писать предварительное условие (или руководство if), чтобы убедиться, что ваш аргумент находится в допустимом диапазоне.
    • Инвариант типа предоставляется бесплатно.
  • Перечисления могут иметь поведение, как и любой другой класс.
  • Вам, вероятно, понадобится такой же объем памяти для использования String s (это зависит от сложности Enum).

Кроме того, каждый из экземпляров Enum - это класс, для которого вы можете определить его индивидуальное поведение.

Кроме того, они гарантируют безопасность потоков при создании экземпляров (когда загружается перечисление), что значительно упростило упрощение Singleton Pattern.

Этот блог иллюстрирует некоторые из его приложений, например State Machine для парсера.

Ответ 8

Полезно знать, что enums аналогичны другим классам с полями Constant и private constructor.

Например,

public enum Weekday
{
  MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
} 

Компилятор компилирует его следующим образом:

class Weekday extends Enum
{
  public static final Weekday MONDAY  = new Weekday( "MONDAY",   0 );
  public static final Weekday TUESDAY = new Weekday( "TUESDAY ", 1 );
  public static final Weekday WEDNESDAY= new Weekday( "WEDNESDAY", 2 );
  public static final Weekday THURSDAY= new Weekday( "THURSDAY", 3 );
  public static final Weekday FRIDAY= new Weekday( "FRIDAY", 4 );
  public static final Weekday SATURDAY= new Weekday( "SATURDAY", 5 );
  public static final Weekday SUNDAY= new Weekday( "SUNDAY", 6 );

  private Weekday( String s, int i )
  {
    super( s, i );
  }

  // other methods...
}

Ответ 9

enum означает перечисление, то есть упоминание (несколько вещей) один за другим.

Перечисление - это тип данных, который содержит фиксированный набор констант.

ИЛИ ЖЕ

enum похоже на class с фиксированным набором экземпляров, известных во время компиляции.

Например:

public class EnumExample {
    interface SeasonInt {
        String seasonDuration();
    }

    private enum Season implements SeasonInt {
        // except the enum constants remaining code looks same as class
        // enum constants are implicitly public static final we have used all caps to specify them like Constants in Java
        WINTER(88, "DEC - FEB"), SPRING(92, "MAR - JUN"), SUMMER(91, "JUN - AUG"), FALL(90, "SEP - NOV");

        private int days;
        private String months;

        Season(int days, String months) { // note: constructor is by default private 
            this.days = days;
            this.months = months;
        }

        @Override
        public String seasonDuration() {
            return this+" -> "+this.days + "days,   " + this.months+" months";
        }

    }
    public static void main(String[] args) {
        System.out.println(Season.SPRING.seasonDuration());
        for (Season season : Season.values()){
            System.out.println(season.seasonDuration());
        }

    }
}

Преимущества enum:

  • enum повышает безопасность типов при проверке во время компиляции, чтобы избежать ошибок во время выполнения.
  • enum может быть легко использован в switch
  • enum может быть пройден
  • enum может иметь поля, конструкторы и методы
  • enum может реализовывать много интерфейсов, но не может расширять любой класс, потому что он внутренне расширяет класс Enum

для большего

Ответ 10

Что такое перечисление

  • enum - это ключевое слово, определенное для перечисления нового типа данных. Типизированные перечисления должны использоваться свободно. В частности, они представляют собой надежную альтернативу простым константам String или int, используемым в гораздо более старых API для представления наборов связанных элементов.

Зачем использовать enum

  • перечисления неявно являются окончательными подклассами java.lang.Enum
  • если перечисление является членом класса, оно неявно является статическим
  • new никогда не может использоваться с перечислением, даже внутри самого перечисления
  • name и valueOf просто используют текст констант enum, тогда как toString может быть переопределен для предоставления любого содержимого, если это необходимо
  • для констант перечисления равно и == равно одному и тому же и может использоваться взаимозаменяемо
  • константы enum неявно являются публичными static final

Заметка

  • Перечисления не могут расширять любой класс.
  • Перечисление не может быть суперклассом.
  • порядок появления констант enum называется их "естественным порядком" и определяет порядок, используемый другими элементами: CompareTo, порядок итераций значений, EnumSet, EnumSet.range.
  • Перечисление может иметь конструкторы, статические блоки и блоки экземпляров, переменные и методы, но не может иметь абстрактных методов.

Ответ 11

Помимо всего сказанного другими. В более раннем проекте, над которым я работал, большая часть общения между сущностями (независимыми приложениями) использовала целые числа, которые представляли небольшой набор. Было полезно объявить набор как enum статическими методами для получения объекта enum из value и наоборот. Код выглядел более чистым, удобство использования и удобство записи в журналы.

enum ProtocolType {
    TCP_IP (1, "Transmission Control Protocol"), 
    IP (2, "Internet Protocol"), 
    UDP (3, "User Datagram Protocol");

    public int code;
    public String name;

    private ProtocolType(int code, String name) {
        this.code = code;
        this.name = name;
    }

    public static ProtocolType fromInt(int code) {
    switch(code) {
    case 1:
        return TCP_IP;
    case 2:
        return IP;
    case 3:
        return UDP;
    }

    // we had some exception handling for this
    // as the contract for these was between 2 independent applications
    // liable to change between versions (mostly adding new stuff)
    // but keeping it simple here.
    return null;
    }
}

Создайте объект enum из полученных значений (например, 1,2), используя ProtocolType.fromInt(2) Напишите в журналы с помощью myEnumObj.name

Надеюсь, что это поможет.

Ответ 12

Enum наследует все методы класса Object и абстрактного класса Enum. Таким образом, вы можете использовать его методы для отражения, многопоточности, серилизации, сопоставимые и т.д. Если вы просто объявляете статическую константу вместо Enum, вы не можете. Кроме того, значение Enum также может быть передано на слой DAO.

Вот пример программы для демонстрации.

public enum State {

    Start("1"),
    Wait("1"),
    Notify("2"),
    NotifyAll("3"),
    Run("4"),
    SystemInatilize("5"),
    VendorInatilize("6"),
    test,
    FrameworkInatilize("7");

    public static State getState(String value) {
        return State.Wait;
    }

    private String value;
    State test;

    private State(String value) {
        this.value = value;
    }

    private State() {
    }

    public String getValue() {
        return value;
    }

    public void setCurrentState(State currentState) {
        test = currentState;
    }

    public boolean isNotify() {
        return this.equals(Notify);
    }
}

public class EnumTest {

    State test;

    public void setCurrentState(State currentState) {
        test = currentState;
    }

    public State getCurrentState() {
        return test;
    }

    public static void main(String[] args) {
        System.out.println(State.test);
        System.out.println(State.FrameworkInatilize);
        EnumTest test=new EnumTest();
        test.setCurrentState(State.Notify);
        test. stateSwitch();
    }

    public void stateSwitch() {
        switch (getCurrentState()) {
        case Notify:
            System.out.println("Notify");
            System.out.println(test.isNotify());
            break;
        default:
            break;
        }
    }
}

Ответ 13

ENUM означает "Перечислимый тип". Это тип данных, имеющий фиксированный набор констант, которые вы сами определяете.

Ответ 14

На мой взгляд, все ответы, которые вы получили до настоящего времени, действительны, но, по моему опыту, я бы сказал в нескольких словах:

Используйте перечисления, если вы хотите, чтобы компилятор проверял правильность значения идентификатора.

В противном случае вы можете использовать строки, как всегда (возможно, вы определили некоторые "соглашения" для своего приложения), и вы будете очень гибкими... но вы не получите 100% -ную защиту от опечаток на ваших строках, и вы будете реализовать их только во время выполнения.

Ответ 15

Enum? Зачем его использовать? Я думаю, что это более понятно, когда вы будете его использовать. У меня такой же опыт.

Скажем, у вас есть операция создания, удаления, редактирования и чтения базы данных.

Теперь, если вы создаете enum как операцию:

public enum operation {
    create("1")
    delete("2")
    edit("3")
    read("4")

    // You may have is methods here
    public boolean isCreate() {
        return this.equals(create);
    }
    // More methods like the above can be written

}

Теперь вы можете объявить что-то вроде:

private operation currentOperation;

// And assign the value for it 
currentOperation = operation.create

Таким образом, вы можете использовать его по-разному. Всегда хорошо иметь enum для конкретных вещей, так как работа с базой данных в приведенном выше примере может контролироваться проверкой currentOperation. Возможно, можно сказать, что это может быть достигнуто с помощью переменных и целочисленных значений. Но я считаю, что Enum - более безопасный и программистский способ.

Другое дело: я думаю, что каждый программист любит логическое, не так ли? Потому что он может хранить только два значения, два конкретных значения. Таким образом, можно думать, что Enum имеет такой же тип средств, где пользователь будет определять, сколько и какой тип значения он будет хранить, просто немного по-другому. :)

Ответ 16

Используйте перечисления для TYPE SAFETY, это функция языка, поэтому вы обычно получаете:

  • Поддержка компилятора (немедленно увидеть проблемы с типом)
  • Поддержка инструментов в IDE (автоматическое завершение в корпусе коммутатора...)

В представлениях могут быть методы, конструкторы, вы даже можете использовать enums внутри enums и комбинировать перечисления с интерфейсами.

Подумайте о перечислениях как типах для замены четко определенного набора int-констант (который Java "унаследовал" от C/С++).

В книге "Эффективная Java 2nd Edition" есть целая глава о них и подробно рассматривается. Также см. этот пост.

Ответ 17

Java позволяет ограничить переменную наличием одного из нескольких предопределенных значений - другими словами, одного значения из списка с перечислением. Использование enums может помочь уменьшить ошибку в коде. Ниже приведен пример enums вне класса:

enums coffeesize{BIG , HUGE , OVERWHELMING }; 
//This semicolon is optional.

Это ограничивает coffeesize наличием либо: BIG, HUGE, либо OVERWHELMING в качестве переменной.

Ответ 18

До сих пор мне никогда не приходилось использовать перечисления. Я читал о них, так как они были введены в тигр версии 1.5 или версии, как это было вызвано в тот же день. Они никогда не решали для меня "проблему". Для тех, кто его использует (и я вижу, что многие из них это делают), я уверен, что это определенно служит какой-то цели. Просто мой 2-й день.

Ответ 19

Здесь много ответов, просто нужно указать два конкретных:

1) Использование в качестве констант в выражении Switch-case. Корпус коммутатора не позволит использовать объекты String для случая. Перечисления пригождаются. Подробнее: http://www.javabeat.net/2009/02/how-to-use-enum-in-switch/

2) Реализация Singleton Design Pattern - снова запустится, возвращается на помощь. Использование здесь: Каков наилучший подход для использования Enum в качестве одноэлементного набора в Java?

Ответ 20

То, что дало мне момент А-Ха, - это осознание: у Enum есть частный конструктор, доступный только через публичное перечисление:

enum RGB {
    RED("Red"), GREEN("Green"), BLUE("Blue");

    public static final String PREFIX = "color ";

    public String getRGBString() {
        return PREFIX + color;
    }

    String color;

    RGB(String color) {
        this.color = color;
    }
}

public class HelloWorld {
    public static void main(String[] args) {
        String c = RGB.RED.getRGBString();
        System.out.print("Hello " + c);
    }
}

Ответ 21

Использование enum над константами помогает с безопасностью типа, потому что если функция принимает перечисление, и вы передаете ему что-либо, кроме перечисления, компилятор будет жаловаться. С константами вы принимаете довольно большой диапазон данных, большинство из которых недействительны.

  • java.util.EnumSet и java.util.EnumMap: добавлены два класса java.util для поддержки перечисления: EnumSet и EnumMap. Они высоки производительность реализации интерфейсов Set и Map соответственно.
  • Все константы, определенные в перечислении, являются public static final. С тех пор они являются статическими, к ним можно получить доступ через EnumName.instanceName.

  • Перечисление может быть объявлено вне или внутри класса, но НЕ в Метод.

  • Добавление новых констант в Enum в Java легко и вы можете добавить новые константы без нарушения существующего кода.

Подробнее о.... Java Enum

Rj

Ответ 22

Что касается того, чтобы сделать код, читаемый в будущем, самый полезный аппроксимируемый случай перечисления представлен в следующем фрагменте:

public enum Items {
    MESSAGES, CHATS, CITY_ONLINE, FRIENDS, PROFILE, SETTINGS, PEOPLE_SEARCH, CREATE_CHAT
}

@Override
public boolean onCreateOptionsMenu(Menu menuPrm) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menuPrm);
    View itemChooserLcl;
    for (int i = 0; i < menuPrm.size(); i++) {
        MenuItem itemLcl  = menuPrm.getItem(i);
            itemChooserLcl = itemLcl.getActionView();
            if (itemChooserLcl != null) {
                 //here Im marking each View' tag by enume values:
                itemChooserLcl.setTag(Items.values()[i]);
                itemChooserLcl.setOnClickListener(drawerMenuListener);
            }
        }
    return true;
}
private View.OnClickListener drawerMenuListener=new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Items tagLcl= (Items) v.getTag();
        switch (tagLcl){
            case MESSAGES: ;
            break;
            case CHATS : ;
            break;
            case CITY_ONLINE : ;
            break;
            case FRIENDS : ;
            break;
            case  PROFILE: ;
            break;
            case  SETTINGS: ;
            break;
            case  PEOPLE_SEARCH: ;
            break;
            case  CREATE_CHAT: ;
            break;
        }
    }
};

Ответ 23

Enum является заменой традиционного определения нескольких статических конечных переменных в Java и очень часто используется, когда у вас есть разумный фиксированный набор констант.

Я вижу, что самое важное преимущество перечисления - это когда вы определяете метод, который принимает постоянный аргумент. Таким образом вы принудительно вызываете вызывающих метод для предопределенных констант и не допускаете их передачи случайных значений констант.

Ссылка: Как использовать перечисления в Java

Ответ 24

По моему опыту, я видел, как использование Enum иногда приводит к тому, что системы очень сложно изменить. Если вы используете Enum для набора значений, специфичных для домена, которые часто меняются, и у него есть много других классов и компонентов, которые зависят от него, вам может потребоваться не использовать Enum.

Например, торговая система, использующая Enum для рынков/обменов. Там много рынков, и почти наверняка будет много подсистем, которым необходимо получить доступ к этому списку рынков. Каждый раз, когда вы хотите, чтобы новый рынок был добавлен в вашу систему, или если вы хотите удалить рынок, возможно, что все под солнцем придется перестраивать и выпускать.

Лучший пример - это что-то вроде типа категории продукта. Скажем, ваше программное обеспечение управляет инвентарем для универмага. Существует много категорий товаров и многие причины, по которым этот список категорий может измениться. Менеджеры могут захотеть создать новую линейку продуктов, избавиться от других производственных линий и, возможно, время от времени реорганизовать категории. Если вам нужно перестроить и перераспределить все свои системы, просто потому, что пользователи хотят добавить категорию продукта, то вы взяли то, что должно быть простым и быстрым (добавив категорию), и сделали его очень сложным и медленным.

Нижняя строка, перечисления хороши, если данные, которые вы представляете, очень статичны с течением времени и имеют ограниченное количество зависимостей. Но если данные сильно меняются и имеют множество зависимостей, то вам нужно что-то динамическое, которое не проверяется во время компиляции (например, таблица базы данных).

Ответ 25

Я бы использовал перечисления в качестве полезного инструмента отображения, избегая нескольких if-else при условии, что некоторые методы реализованы.

public enum Mapping {

    ONE("1"),
    TWO("2");

    private String label;

    private Mapping(String label){
        this.label = label;
    }

    public static Mapping by(String label) {

        for(Mapping m: values() {
            if(m.label.equals(label)) return m;
        }

        return null;
    }

}

Таким образом, метод by(String label) позволяет вам получить значение Enumerated, неперечисленное. Кроме того, можно создать сопоставление между двумя перечислениями. Также можно попробовать "от 1 до многих" или "от многих до многих" в дополнение к соотношению по умолчанию "один к одному"

В конце концов, enum - это класс Java. Таким образом, вы можете иметь внутри него метод main, который может быть полезен, когда вам нужно немедленно выполнить некоторые операции отображения на args.

Ответ 26

Вместо того, чтобы делать кучу объявлений const int

Вы можете сгруппировать их все в 1 enum

Так что все это организовано общей группой, к которой они принадлежат