Вопрос-ответ

What's the advantage of a Java enum versus a class with public static final fields?

В чем преимущество Java enum по сравнению с классом с общедоступными статическими конечными полями?

Я хорошо знаком с C #, но начинаю больше работать на Java. Я ожидал узнать, что перечисления в Java в основном эквивалентны перечислениям в C #, но, видимо, это не так. Изначально я был рад узнать, что Java enums могут содержать несколько фрагментов данных, что кажется очень выгодным (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html). Однако с тех пор я обнаружил отсутствие множества функций, которые являются тривиальными в C #, таких как возможность легко присваивать элементу enum определенное значение и, следовательно, возможность преобразовывать целое число в enum без значительных усилий (т. Е. Преобразовывать целочисленное значение в соответствующее Java Enum).

Итак, мой вопрос заключается в следующем: есть ли какие-либо преимущества у Java enums по сравнению с классом с кучей общедоступных статических конечных полей? Или это просто обеспечивает более компактный синтаксис?

РЕДАКТИРОВАТЬ: Позвольте мне внести ясность. В чем преимущество Java enums перед классом с кучей общедоступных статических конечных полей того же типа? Например, в примере planets по первой ссылке, в чем преимущество enum перед классом с этими общедоступными константами:

public static final Planet MERCURY = new Planet(3.303e+23, 2.4397e6);
public static final Planet VENUS = new Planet(4.869e+24, 6.0518e6);
public static final Planet EARTH = new Planet(5.976e+24, 6.37814e6);
public static final Planet MARS = new Planet(6.421e+23, 3.3972e6);
public static final Planet JUPITER = new Planet(1.9e+27, 7.1492e7);
public static final Planet SATURN = new Planet(5.688e+26, 6.0268e7);
public static final Planet URANUS = new Planet(8.686e+25, 2.5559e7);
public static final Planet NEPTUNE = new Planet(1.024e+26, 2.4746e7);

Насколько я могу судить, ответ касабланки - единственный, который удовлетворяет этому.

Переведено автоматически
Ответ 1

  1. Безопасность типов и значений.

  2. Гарантированный синглтон.

  3. Возможность определять и переопределять методы.

  4. Возможность использовать значения в операторах switch statement case без каких-либо оговорок.

  5. Встроенная последовательность значений с помощью ordinal().

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

  7. EnumSet и EnumMap классы.

Ответ 2

Технически действительно можно рассматривать enums как класс с набором типизированных констант, и фактически именно так константы enum реализуются внутри. Использование enum однако дает вам полезные методы (Enum javadoc), которые в противном случае вам пришлось бы реализовать самостоятельно, например Enum.valueOf.

Ответ 3

Никто не упоминал о возможности использовать их в switch операторах; я добавлю и это.

Это позволяет использовать произвольно сложные перечисления чистым способом, без использования instanceofпотенциально запутанных if последовательностей или значений, отличных от строки / int. Канонический пример - конечный автомат.

Ответ 4

Основным преимуществом является безопасность типов. С набором констант может использоваться любое значение того же встроенного типа, что приводит к ошибкам. С enum могут использоваться только применимые значения.

Например

public static final int SIZE_SMALL  = 1;
public static final int SIZE_MEDIUM = 2;
public static final int SIZE_LARGE = 3;

public void setSize(int newSize) { ... }

obj.setSize(15); // Compiles but likely to fail later

против

public enum Size { SMALL, MEDIUM, LARGE };

public void setSize(Size s) { ... }

obj.setSize( ? ); // Can't even express the above example with an enum
java enums