Java Enums может иметь поведение? - PullRequest
14 голосов
/ 07 апреля 2009

В Java Enum может делать великие вещи, которые делает Enums, но также может иметь методы (поведение и логику). Какое преимущество это имеет по сравнению с использованием класса с использованием enum? Простые примеры, иллюстрирующие эту точку зрения, также приветствуются.

Ответы [ 7 ]

17 голосов
/ 07 апреля 2009

Вот простой пример:

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);
}
9 голосов
/ 07 апреля 2009

Enum типы также отличный способ реализовать настоящие синглтоны.

Классические одноэлементные шаблоны в Java обычно включают частные конструкторы и общедоступные статические фабричные методы, но все еще уязвимы для реализации посредством отражения или (де) сериализации. Тип enum защищает от этого.

7 голосов
/ 07 апреля 2009

Я не совсем уверен, где название вопроса вписывается в остальную часть. Да, у перечислений Java есть поведение. Они также могут иметь состояние, хотя оно действительно должно действительно быть неизменным. (Идея изменяемого значения перечисления довольно пугающая ИМО.)

Перечисление в Java - это, по сути, фиксированный набор объектов. Преимущество состоит в том, что вы знаете, что если у вас есть ссылка этого типа, она всегда или null или один из известных наборов.

Лично я действительно люблю перечисления Java и хотел бы, чтобы в C # они тоже были - они гораздо более объектно-ориентированы, чем перечисления в C #, которые в основном являются "именованными числами". Есть несколько «ошибок» с точки зрения порядка инициализации, но они, как правило, потрясающие.

2 голосов
/ 07 апреля 2009

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

Вы можете эмулировать «известный фиксированный набор возможных экземпляров» с обычными классами (шаблон «typesafe enum», описанный в бесчисленных книгах и статьях), но это довольно трудоемкий (повторяется для каждого такого класса), чтобы заставить его работать действительно правильно в отношении Serialization, equals () и hashCode () и, возможно, некоторых других вещей, которые я забыл. Перечни языкового уровня избавят вас от этой работы. И, как упоминалось выше, в выражениях switch могут использоваться только перечисления уровня языка.

2 голосов
/ 07 апреля 2009

Поскольку экземпляры enum являются одиночными, вы можете использовать их в операторах switch или с == для проверки равенства.

1 голос
/ 07 апреля 2009

В нашем проекте мы используем Enums для нескольких вещей, но, возможно, наиболее заметно для целей i18n - каждому фрагменту показанного текста присваивается Enum. Класс Enum имеет метод String-returning, который проверяет используемый языковой стандарт и выбирает правильный перевод из коллекции переводов во время выполнения.

Это служит двойному назначению - вы получаете завершение кода из вашей IDE, а также никогда не забываете переводить строку.

Использование очень простое, до такой степени, что приводить пример практически невозможно, но вот как можно использовать translation-enum

System.out.println(Translations.GREET_PERSON.trans()+" "+user.getName());

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

System.out.println(Translations.GREET_PERSON.trans(user.getName());
0 голосов
/ 21 декабря 2017

Взгляните на классы времени 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 

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...