В Java Enum может делать великие вещи, которые делают Enums, но также может иметь методы (поведение и логику). Какое преимущество имеет преимущество при использовании класса с использованием перечисления? Простые примеры, чтобы проиллюстрировать этот пункт, также приветствуются.
У Java Enums может быть поведение?
Ответ 1
Вот простой пример:
enum RoundingMode {
UP {
public double round(double d) {
return Math.ceil(d);
}
},
DOWN {
public double round(double d) {
return Math.floor(d);
}
};
public abstract double round(double d);
}
Ответ 2
Enum
также являются отличным способом реализации истинных синглетонов.
Классические одноэлементные шаблоны в Java обычно включают частные конструкторы и общедоступные статические методы factory, но все еще уязвимы для создания экземпляров посредством отражения или (дезадаптации). Тип перечисления защищает от этого.
Ответ 3
Я не совсем уверен, где заголовок вопроса подходит ко всему остальному. Да, перечисления Java имеют поведение. У них может быть и государство, хотя оно действительно должно быть действительно неизменным. (Идея изменчивого значения enum довольно страшная IMO.)
Перечисление в Java - это фиксированный набор объектов, в основном. Преимущество состоит в том, что вы знаете, что если у вас есть ссылка на этот тип, он всегда либо null
, либо один из известных наборов.
Лично я действительно люблю перечисления Java и хочу, чтобы у С# их тоже - они намного объектно-ориентированные, чем перечисления С#, которые в основном являются "именованными номерами". Есть несколько "gotchas" с точки зрения порядка инициализации, но они обычно являются fab.
Ответ 4
Поскольку экземпляры перечисления являются одноточечными, вы можете использовать их в операторах switch
или с помощью ==
для проверки равенства.
Ответ 5
В принципе, классы перечисления Java являются (я не считаю, что существует разница на уровне байт-кода), с дополнительным преимуществом наличия известного фиксированного набора возможных экземпляров и возможности использования их в операторах switch.
Вы можете эмулировать "известный фиксированный набор возможных экземпляров" с обычными классами (шаблон "typafe enum", описанный в бесчисленных книгах и статьях), но это довольно некоторая работа (повторяющаяся для каждого такого класса), чтобы заставить ее работать действительно правильно в отношении сериализации, equals() и hashCode() и, возможно, некоторые другие вещи, которые я забыл. Перечисления на уровне языка избавляют вас от этой работы. И, как упоминалось выше, в операторах switch могут использоваться только перечисления уровня языка.
Ответ 6
В нашем проекте мы используем Enums для нескольких вещей, но, возможно, наиболее заметно для целей i18n - каждому изображенному тексту предоставляется Enum. Класс Enum имеет метод String-return, который проверяет используемый Locale и выбирает правильный перевод из коллекции переводов во время выполнения.
Это служит для двух целей: вы получаете завершение кода из своей среды IDE, а также никогда не забываете переводить строку.
Использование очень просто, до такой степени, что это дает пример, но здесь, как можно использовать трансляцию-перечисление
System.out.println(Translations.GREET_PERSON.trans()+" "+user.getName());
Или, если вы хотите быть фантазией, укажите аргументы Enum accept, которые с некоторой магической строкой будут помещены в помеченную позицию в строке переводов
System.out.println(Translations.GREET_PERSON.trans(user.getName());
Ответ 7
Взгляните на классы времени java/joda, где перечисления выполняют чертовски много работы.
Вот пример java.time.Month:
public enum Month implements TemporalAccessor, TemporalAdjuster {
JANUARY,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER;
private static final Month[] ENUMS = Month.values();
public static Month of(int month) {
if (month < 1 || month > 12) {
throw new DateTimeException("Invalid value for MonthOfYear: " + month);
}
return ENUMS[month - 1];
}
// About a dozen of other useful methods go here
}