В Java Enum может делать то, что делают Enums, но также может иметь методы (поведение и логика). Какое преимущество имеет преимущество при использовании класса с использованием перечисления? Простые примеры, чтобы проиллюстрировать этот пункт, также приветствуются.Переменные Java могут иметь поведение?
ответ
Вот простой пример:
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);
}
Я не совсем уверен, где заголовок вопроса подходит ко всему остальному. Да, перечисления Java имеют поведение. У них тоже может быть состояние, хотя это действительно так, действительно быть неизменным. (Идея изменчивого значения enum довольно страшная IMO.)
Перечисление в Java - это фиксированный набор объектов, в основном. Преимущество в том, что вы знаете, что если у вас есть ссылка на этот тип, то всегда либо null
, либо один из известных наборов.
Лично я действительно люблю перечисления Java и хочу, чтобы у C# их тоже было - они намного объективны, чем перечисления C#, которые в основном являются «именованными номерами». Есть несколько «gotchas» с точки зрения порядка инициализации, но они, как правило, потрясающие.
Не может эмулировать Java перечислений с C# классов? –
@Vilx: Конечно, вы можете. Перед Java 5 вы можете написать свои собственные классы, чтобы создавать типы объектов enum enum. (Ну, вы все равно можете, конечно, просто нечего.) – Eddie
Vilx: Вы можете, но это немного противно. В основном вы используете абстрактный базовый тип с частным конструктором и извлекаете из него * вложенные * типы, которые могут вызывать частный конструктор. –
В нашем проекте мы используем Enums для нескольких вещей, но, возможно, наиболее заметно для целей i18n - каждому изображенному тексту предоставляется Enum. Класс Enum имеет метод String-return, который проверяет используемый Locale и выбирает правильный перевод из коллекции переводов во время выполнения.
Это двойное назначение - вы получаете завершение кода из своей IDE, а также никогда не забываете переводить строку.
Использование очень просто, к тому, что это почти rendundant привести пример, но вот как можно было бы использовать перевод-перечисление
System.out.println(Translations.GREET_PERSON.trans()+" "+user.getName());
Или, если вы хотите быть фантазии, есть Enum принимать аргументы, которые будут с некоторой магической работы со строками, вставляться в отмеченной позиции в строке переводов
System.out.println(Translations.GREET_PERSON.trans(user.getName());
Интересное использование, но похоже, что вы можете получить такое же поведение из серии статических методов в классе. Думаю, я не вижу преимущества использования перечисления. – Dave
Перечисления намного проще добавлять при необходимости. Они тоже осведомлены о себе - вы можете получить строку перечисления непосредственно в trans() - поэтому вы можете использовать это как ключевое слово для сопоставления в вашей таблице translations –
Enum
типы также являются отличным способом реализации истинных синглетонов.
Классические одноэлементные шаблоны в Java обычно включают частные конструкторы и общедоступные статические методы, но все еще уязвимы для создания экземпляров посредством отражения или (дезадаптации). Тип перечисления защищает от этого.
Хотя вы получаете некоторый нечетный метод «бесплатно». (В любом случае, синглтоны - зло.) –
Я не понимаю комментария. –
Интересные точки. Как перевязка защищает от отражения и десериализации? Наверное, я спрашиваю, что на самом деле мешает мне создавать экземпляр enum через отражение? Вызывает ли компилятор исключенное исключение? – Dave
Поскольку экземпляры перечисления являются одиночными, вы можете использовать их в операциях switch
или с ==
для проверки равенства.
В основном, перечисления Java являются классами (я не верю, что существует разница на уровне байт-кода), с дополнительным преимуществом наличия известного фиксированного набора возможных экземпляров и возможности использования их в операторах switch ,
Вы можете эмулировать «известный фиксированный набор возможных экземпляров» с обычными классами (шаблон «typafe enum», описанный в бесчисленных книгах и статьях), но это довольно некоторая работа (повторяющаяся для каждого такого класса), чтобы получить ее работают действительно правильно в отношении сериализации, equals() и hashCode() и, возможно, некоторые другие вещи, которые я забыл. Перечисления на уровне языка избавляют вас от этой работы. И, как упоминалось выше, в операторах switch могут использоваться только перечисления уровня языка.
Это классы, но есть разница на уровне байт-кода. Во-первых, классы перечисления имеют флаг ACC_ENUM. См. Http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf. –
Взгляните на классы времени 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
}
- 1. Почему категории не могут иметь переменные экземпляра?
- 2. 2 Переменные исходы не могут иметь два?
- 3. Java, могут ли переменные regex принимать переменные?
- 4. Почему классы сущностей JPA не могут иметь настраиваемые переменные экземпляра?
- 5. Java и MySQL могут иметь журнал отладки?
- 6. переменные могут вызвать методы в языке Java
- 7. Могут ли переменные java быть неограниченным шаблоном?
- 8. Могут ли переменные-члены и переменные локального метода иметь одно и то же имя?
- 9. Как свойства могут иметь свойства и методы?
- 10. Могут ли проекты maven иметь несколько родителей?
- 11. Переменные не могут быть разрешены
- 12. Могут ли модули иметь свойства?
- 13. Могут ли лямбды иметь докстры?
- 14. PHP переменные сессии поведение
- 15. androidannotations не могут найти переменные
- 16. Могут ли набираться переменные JavaScript?
- 17. Переменные, которые могут быть эхом
- 18. Могут ли переменные быть украшены?
- 19. Локально объявленные переменные не могут быть проверены
- 20. Могут ли переменные C++ изменять UNLIKE Java Strings?
- 21. Java RMI: как иметь разные переменные для каждого клиента?
- 22. Как иметь переменные с динамическими типами данных в Java?
- 23. Java: Как иметь тип списка принимать переменные аргументы
- 24. Возможно ли иметь переменные условия в методе Java?
- 25. Могут ли модули иметь свойства так же, как объекты могут?
- 26. как переменные могут быть присвоены типу интерфейса?
- 27. Как иметь незащищенные переменные состояния в Go?
- 28. $ _SESSION переменные, показывающие неожиданное поведение
- 29. Почему эти переменные не могут быть решены?
- 30. Python Переменные Referecing - неожиданное поведение с молнией
Как бы вы использовали это в коде? Я просто это делаю? double foo = RoundingMode.round (20.3); Или вы могли бы перечислить перечисление на дочернее перечисление? Я отбрасываю абстрактным методом. – Dave
Абстрактный метод переопределяется вложенными классами, используемыми UP и DOWN. Вы бы использовали его в коде следующим образом: double doMath (RoundMode m, double x, double y) {double d; ... d = m.round (d); ... return d; } Вы должны передать в RoundingMode.UP или RoundingMode.DOWN в качестве первого параметра. –
Спасибо! Не знаю, как я к этому отношусь, но я это понимаю сейчас;) – Dave