Пример работы с перечислениями (enum) в Java

Информация в посте приведена на основе книги Эккель Б. Философия Java (4-е издание)

java_enum.jpg

Ключевое слово enum создает новый тип с ограниченным набором именованных значений, и работать с этими значениями можно как с обычными компонентами программы.

Мы можем получить список констант перечисления, вызвав для enum метод values(). Метод values() создает массив констант перечисления, следующих в порядке их объявления, так что полученный массив может использоваться в цикле foreach.

При создании перечисления компилятор генерирует соответствующий класс. Этот класс автоматически наследует от класса java.lang.Enum. Элементы enum это статически доступные экземпляры enum-класса. Некоторые полезные возможности базового класса продемонстрированы в следующем примере:

class Example1{  
    public enum Season {WINTER, SPRING, SUMMER, FALL};

    Season w = Season.WINTER;

    public static void main(String[] args) {  
        for (Season s : Season.values())  
            System.out.println(s.ordinal() + ": " + s);  
    }  
}

Метод ordinal() возвращает значение int, определяющее порядок объявления экземпляров перечисления начиная с нуля. Экземпляры всегда можно безопасно сравнивать с оператором ==, a методы equals() и hashCode() автоматически создаются за вас. Класс Enum реализует интерфейс Comparable, поэтому в нем присутствует метод compareTo( ), кроме того, реализуется интерфейс Serializable.

Метод name() возвращает имя точно в таком виде, в каком оно было объявлено; эту же информацию возвращает метод toString(). Статический метод valueOf() возвращает экземпляр перечисления, соответствующий переданному строковому имени, или возбуждает исключение при отсутствии подходящего экземпляра.

Пример получения элемент enum по его строковому представлению

String name = "SUMMER"; 
Season season = Season.valueOf(name);

Перечисление не может использоваться при наследовании, но в остальном оно работает как обычный класс. Это означает, что в перечисление можно добавлять новые методы.

Допустим, вы решили определить для перечисления другое описание - вместо реализации toString() по умолчанию, которая просто выдает имя экземпляра перечисления. Для этого можно предоставить конструктор для сохранения расширенной информации, a также дополнительные методы для передачи расширенного описания:

class Example2{  
    public enum Season {
        WINTER("Cold season"), 
        SPRING("Cool season"), 
        SUMMER("Hot season"), 
        FALL("Cool season");

        private String description;

        private Season(String description) {
            this.description = description;
        }

        public String getDescription() {return description;}
    };

    public static void main(String[] args) {  
        for (Season s : Season.values())  
            System.out.println(s + ": " + s.getDescription());  
    }  
}

Обратите внимание: если вы собираетесь определять методы, то последовательность экземпляров перечисления должна завершаться символом ;. Кроме того, по правилам Java перечисление должно начинаться с определения экземпляров. При попытке определить их после методов или полей компилятор выдает ошибку.

Конструктор и методы строятся пo той же схеме, что и в обычном классе‚ потому что перечисление (с некоторыми ограничениями) и является обычным классом.

Одна из самых удобных возможностей перечисления связана с их использованием в команде switch.

class Example3{  
    public enum Season {WINTER, SPRING, SUMMER, FALL};

    public static void main(String[] args) {  
        Season w = Season.WINTER;
        switch(w) {
            case WINTER:
            case SPRING:
            case FALL:
                System.out.println("Working ...");  
                break;
            case SUMMER:
                System.out.println("Relaxation ...");  
                break;

        }
    }  
}

blog comments powered by Disqus