Информация в посте приведена на основе книги Эккель Б. Философия Java (4-е издание)
Ключевое слово 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; } } }