Перечисление в Java. Преимущества?

Какие преимущества делает enum в Java похожим на класс, а не просто на набор констант, как в C/C++?

10 ответов

Решение

Вы получаете бесплатную проверку правильности значений времени компиляции. С помощью

public static int OPTION_ONE = 0;
public static int OPTION_TWO = 1;

не обеспечивает

void selectOption(int option) {
...
}

будет принимать только 0 или 1 в качестве значения параметра. Используя перечисление, это гарантировано. Более того, это приводит к большей самодокументированности кода, потому что вы можете использовать завершение кода, чтобы увидеть все значения перечисления.

Тип безопасности является одной из причин.

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

AddItem(HttpMethod.POST, ProductEntry.class),

Перечисления Java 5 возникли из шаблона типизированных перечислений из " Эффективной Java" Джошуа Блоха (первое издание), чтобы избежать ошибок перечислений в C/C++/C# (которые являются просто тонко завуалированными int-константами) и использования в Java final статические int константы.

В первую очередь int-константы и int-перечисления не безопасны. Вы можете передать любое значение типа int. В C / C++ вы можете сделать это:

enum A { one, two, three };
enum B { beef, chicken, pork } b = beef;

void func(A a) { ... }
func((A)b);

К сожалению, в типизированном шаблоне enum из Effective Java было много общего, но не все это очевидно. Наиболее заметным является то, что вам пришлось переопределить закрытый метод readResolve остановить Java, создавая новые экземпляры при десериализации, что нарушит простую проверку ссылок (т. е. с использованием == оператор вместо equals()).

Итак, перечисления Java 5 предлагают следующие преимущества перед целыми:

  • Тип безопасности;
  • Перечисления Java 5 могут иметь поведение и реализовывать интерфейсы;
  • Перечисления Java 5 имеют некоторые чрезвычайно легкие структуры данных, такие как EnumSet а также EnumMap,

Java 5 перечисляет эти преимущества перед использованием только классов:

  • Менее подверженный ошибкам шаблон (частный конструктор, readResolve() так далее);
  • Семантическая корректность. Вы видите, что что-то является перечислением, и вы знаете, что оно просто представляет значение. Вы видите класс, и вы не уверены. Может быть, где-то есть метод статической фабрики и т. Д. Перечисления Java 5 гораздо более четко указывают на намерение.

В дополнение к повышению безопасности типов вы также можете определить пользовательское поведение в ваших перечислениях (некоторые хорошие примеры приведены в Effective Java).

Перечисления - это уже класс в Java.

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

Вы можете использовать перечисления для эффективной реализации Singletons ^^:

public enum Elvis {
    INSTANCE
}

Создание enum ссылочного типа, который может содержать фиксированный набор констант, привело к эффективной реализации Map, такой как EnumMap, и реализации Set, такой как EnumSet (классы JDK).

Из Javadoc EnumMap:
Специализированная реализация Map для использования с ключами типа enum. Все ключи в карте перечисления должны происходить из единственного типа перечисления, который указывается, явно или неявно, при создании карты. Enum карты представлены внутри как массивы. Это представление чрезвычайно компактно и эффективно.

EnumMap сочетает в себе богатство и безопасность типов Map со скоростью массива ( Effective Java).

Преимущества использования перечислений: объект может быть создан для работы так же, как перечисления. Фактически, перечисления даже не были включены в язык Java до версии 5.0. Однако перечисления делают код более читабельным и предоставляют меньше места для ошибок программиста.

OCA Java SE 7 Programmer I Учебное пособие

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

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

Единственным реальным преимуществом является то, что он может быть использован в switch заявление. Все остальные вещи, на которые способен enum, можно просто сделать с помощью простого ванильного класса с private конструктор, чьи экземпляры в свою очередь объявлены как public static final поля рассматриваемого класса (типобезопасный шаблон). Другое преимущество enum состоит в том, что он делает код менее многословным, чем вы бы сделали с простым классом vanilla.

Но если я не ошибаюсь, в C++ (или это был C#?) Вы можете использовать String в switch заявление. Так что преимущество перечислений в Java ничтожно по сравнению с C++. Однако то же самое было предложено для Java 7, но я не уверен, что это удастся.

Другие вопросы по тегам