что такое перечисления в java

Загадки Enum’ов

Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: «Почему так?».

Давайте попробуем разобраться.

Порядок инициализации

В отличие от некоторых других языков программирования в Java перечисления являются полноценными классами. Конечно, есть некоторые особенности, например:

Хорошо, смирились с запретами. Но можем ли мы ожидать, что остальные языковые конструкции работают так же, как в остальной Java? Например, порядок инициализации объектов.

Давайте проверим. Для этого напишем такое перечисление:

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

В обычных классах при инициализации первого объекта кодовые блоки выполняются в следующем порядке:

Для перечисления же мы увидим в консоли следующее:

Как же так? Почему статический блок был вызван последним?

Для ответа на этот вопрос давайте прогоним скомпилированный класс через Java Class File Disassembler и вручную переведем дизассемблированный код в java код. Дизассемблинг выполняется командой:

Для самых любопытных привожу результат исполнения команды.

После ручного перевода в Java код получим следующее (не имеющий отношения к рассматриваемой теме код опущен):

Что же мы видим? Значения перечисления превратились в статические финальные поля. Выражения из кодового блока и конструктора переехали в конструктор. Выражения из статического блока остались в статическом блоке, но до их вызова добавился код создания экземпляров.

Получается, что при первом обращении к классу перечисления первым делом исполняется статический блок. Все как в обычных классах. Первое, что делается в статическом блоке — инициализируются финальные поля класса. Это влечет за собой вызов кода, объявленного в конструкторе, и в консоль дважды выводится

И только после этого исполняется код из статического блока оригинального класса.

Теперь мы знаем в какой класс преобразуется enum при компиляции, и порядок исполнения кодовых блоков становится понятен.
Для того чтобы не держать в памяти последовательность преобразований, приводящую к странному поведению, предлагаю запомнить следующее:

Значения, объявленные в перечислении — это статические финальные поля того же типа, что и класс. Инициализация этих полей происходит в статическом блоке до всех остальных статических выражений.

Отсутствующие методы

Если попробовать в IDE написать любое перечисление, поставить точку и вызвать автодополнение, то он предложит еще два метода:

В исходниках класса Enum таких методов нет, но они как-то появляются в каждом перечислении.

Чтобы разобраться, обратимся к документации. Из нее мы узнаем, что два этих метода объявлены неявно. Почему неявно? Дело в том, что в отличие от других методов класса Enum эти методы не получается реализовать в абстрактном классе. Метод values() возвращает массив со всеми значениями перечисления, а класс Enum о них ничего не знает. Метод valueOf(String) возвращает конкретное значение перечисления по его названию. Можно было бы в нем вызвать метод valueOf(Class, String) :

Но ничего не выходит из-за того, что класс E невозможно извлечь в статическом контексте.

Теперь мы понимаем, что данные методы генерируются компилятором. Но какая же у них реализация? В JLS она не приведена, и в исходниках JDK ее тоже не найти.

Метод valueOf(String) реализуется с помощью вызова тезки:

Обобщая знания о неявных методах и порядке инициализации, давайте запишем как может быть представлено перечисление Pine из начала статьи в виде обычного класса:

Заключение

Странности в перечислениях вызваны архитектурными решениями и ограничениями, выбранными разработчиками Java. С помощью дизассемблирования нам удалось узнать, как перечисления инициализируются, и как в них реализованы неявные методы.

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

Источник

что такое перечисления в java. facebook. что такое перечисления в java фото. что такое перечисления в java-facebook. картинка что такое перечисления в java. картинка facebook. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".что такое перечисления в java. twitter. что такое перечисления в java фото. что такое перечисления в java-twitter. картинка что такое перечисления в java. картинка twitter. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".что такое перечисления в java. tumblr. что такое перечисления в java фото. что такое перечисления в java-tumblr. картинка что такое перечисления в java. картинка tumblr. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".что такое перечисления в java. facebook. что такое перечисления в java фото. что такое перечисления в java-facebook. картинка что такое перечисления в java. картинка facebook. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".что такое перечисления в java. twitter. что такое перечисления в java фото. что такое перечисления в java-twitter. картинка что такое перечисления в java. картинка twitter. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".что такое перечисления в java. tumblr. что такое перечисления в java фото. что такое перечисления в java-tumblr. картинка что такое перечисления в java. картинка tumblr. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".

что такое перечисления в java. enums java. что такое перечисления в java фото. что такое перечисления в java-enums java. картинка что такое перечисления в java. картинка enums java. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".

Привет! Теме что такое Enums (перечисления) мы посвятим 3 статьи:

Ниже наша первая статья. Приятного прочтения.

Что такое Enums

что такое перечисления в java. enums java tea 1. что такое перечисления в java фото. что такое перечисления в java-enums java tea 1. картинка что такое перечисления в java. картинка enums java tea 1. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".что такое перечисления в java. enums java cappucino. что такое перечисления в java фото. что такое перечисления в java-enums java cappucino. картинка что такое перечисления в java. картинка enums java cappucino. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".что такое перечисления в java. enums java coffee. что такое перечисления в java фото. что такое перечисления в java-enums java coffee. картинка что такое перечисления в java. картинка enums java coffee. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".

«Зима, весна, лето, осень?»

что такое перечисления в java. enums java winter. что такое перечисления в java фото. что такое перечисления в java-enums java winter. картинка что такое перечисления в java. картинка enums java winter. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".что такое перечисления в java. enums java spring. что такое перечисления в java фото. что такое перечисления в java-enums java spring. картинка что такое перечисления в java. картинка enums java spring. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".что такое перечисления в java. enums java summer. что такое перечисления в java фото. что такое перечисления в java-enums java summer. картинка что такое перечисления в java. картинка enums java summer. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".что такое перечисления в java. enums java fall. что такое перечисления в java фото. что такое перечисления в java-enums java fall. картинка что такое перечисления в java. картинка enums java fall. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".

В жизни часто у нас есть выбор из ограниченного количества вариантов. Это можно сравнить с «меню», из которого мы можем выбирать.

Как представить такое «меню» в коде? Как говорится, лучше один раз увидеть:

Вот мы и создали наш первый Enum! Выглядит просто, правда?

Давайте обратим внимание на ключевые моменты:

что такое перечисления в java. Enums java IDE. что такое перечисления в java фото. что такое перечисления в java-Enums java IDE. картинка что такое перечисления в java. картинка Enums java IDE. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".

что такое перечисления в java. Enums java private modificator. что такое перечисления в java фото. что такое перечисления в java-Enums java private modificator. картинка что такое перечисления в java. картинка Enums java private modificator. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".

Если же enum будет «внутри» класса, он может быть объявлен private:

что такое перечисления в java. Enums java private. что такое перечисления в java фото. что такое перечисления в java-Enums java private. картинка что такое перечисления в java. картинка Enums java private. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".

что такое перечисления в java. Capture d%E2%80%99%C3%A9cran 2018 05 18 %C3%A0 18.23.33. что такое перечисления в java фото. что такое перечисления в java-Capture d%E2%80%99%C3%A9cran 2018 05 18 %C3%A0 18.23.33. картинка что такое перечисления в java. картинка Capture d%E2%80%99%C3%A9cran 2018 05 18 %C3%A0 18.23.33. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".

В конце мы написали точку с запятой.

Пример 1

Мы уже описывали один enum выше. Давайте создадим такой же, только для наглядности назовем его не myEnum, а Seasons(«времена года»):

Источник

Перечисления enum

Перечисления создаются с использованием ключевого слова enum. Создадим перечисление семейства кошачьих:

Идентификаторы в фигурных скобках называются константами перечисления. Каждый из них явно объявлен как открытый статический финальный член класса Cat. Объявив перечисление, вы можете создавать переменные этого типа. Но делать это нужно без оператора new, а в упрощенном виде. Объявим переменную manul перечислимого типа Cat.

Вы можете присвоить переменной только те значения, которые определены в перечислении, например:

Обратите внимание, что во время присваивания вы указываете и тип Cat.

Использование перечисляемых переменных позволят избежать ошибок. Например, мы хотим использовать только числа 1, 2, 3 и такой способ не позволит использовать числа 0, 5, 9 и т.д.

Перечислимые константы можно проверить на равенство:

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

Метод values()

Автоматически предопределённый метод для перечисления values() возвращает массив, содержащий список констант перечисления.

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

Метод valueOf(String string)

Автоматически предопределённый метод для перечисления valueOf() возвращает константу перечисления, значение которой соответствует строке, переданной в параметре.

Метод ordinal()

У перечислений есть несколько удобных методов. Например, вы можете получить значение, которое указывает позицию константы в списке констант перечисления (порядковое значение или ordinal value), с помощью метода ordinal(). Порядковые значения начинаются с нуля.

Методы compareTo() и equals()

Также можно сравнивать порядковые значения констант одного и того же перечисления с помощью метода compareTo(). Или сравнить на эквивалентность через метод equals().

Увлекаться не стоит из-за большого потребления памяти. Сравним.

По этой причине на сегодняшний день в Android рекомендуется избегать enum. Хотя в последнее время я встречал использование перечислений в исходных кодах Android.

Источник

Перечисления enum

Синтаксис перечисления enum

Описание с помощью enum типа данных Season для хранения времени года можно представить в следующем виде :

Простой пример использования enum :

В результате выполнения данного кода в консоль будет выведен текст SPRING.

В консоль будет выведено :

Элементы перечисления enum

Название и порядковый номер элемента enum

Пример использования методов enum для извлечения информации об объекте :

В консоле будет представлено:

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

Довольно часто возникает задача необходимости получения элемента enum по его строковому представлению. Для этих целей в каждом enum-классе компилятор автоматически создает специальный статический метод : public static EnumClass valueOf (String name), который возвращает элемент перечисления EnumClass с названием, равным name. Например:

Получение элементов перечисления

Если необходимо получить список всех элементов enum-класса во время выполнения, то для этих целей в следует использовать метод: public static EnumClass[] values(). Например:

В консоль будет выведено:

Необходимо иметь в виду, что ни метод valueOf(), ни метод values() не определены в классе java.lang.Enum. Они автоматически добавляются на этапе компиляции enum-класса.

Добавление методов в enum-класс

Можно добавлять собственные методы как в enum-класс, так и в его элементы:

Тот же пример, но с полиморфизмом:

Наследование в enum

С помощью enum в Java можно реализовать иерархию классов, объекты которой создаются в единственном экземпляре и доступны статически. При этом элементы enum могут содержать собственные конструкторы. Пример:

Здесь объявляется перечисление Type с тремя элементами INT, INTEGER и STRING. Компилятор создаст следующие классы и объекты:

Три производных класса будут созданы с полиморфным методом Object parse (String) и конструктором Type (. boolean). При этом объекты классов INT, INTEGER и STRING существуют в единственном экземпляре и доступны статически. В этом можно убедиться, выполнив следующий код :

Результат выполнения кода :

Таким образом, компилятор создал класс Type и 3 nested класса, производных от Type.

Декомпилированный enum-class с наследованием

В подтверждение вышесказанному можно привести результат декомпиляции перечисления Type из примера выше:

Перечисления и параметрический полиморфизм

Источник

Перечисления в Java (java enum)

Предистория

Конструкция enum

Начнем с примера. Давайте опишем с помощью enum тип данных для хранения времени года:

Ну и простой пример его использования:

В результате выполнения которого на консоль будет выведено SUMMER. Думаю, что пример очевиден и в пояснениях не нуждается.

На консоль будет выведено:

Название и порядковый номер элемента enum

Как уже было сказано ранее любой enum-класс наследует java.lang.Enum, который содержит ряд методов полезных для всех перечислений. Пример:

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

Довольно часто возникает задача получить элемент enum по его строковому представлению. Для этих целей в каждом enum-классе компилятор автоматически создает специальный статический метод: public static EnumClass valueOf(String name), который возвращает элемент перечисления EnumClass с названием, равным name. Пример использования:

Получение всех элементов перечисления

Иногда необходимо получить список всех элементов enum-класса во время выполнения. Для этих целей в каждом enum-классе компилятор создает метод:
public static EnumClass[] values(). Пример использования:

Обратите внимание, что ни метод valueOf(), ни метод values() не определен в классе java.lang.Enum. Вместо этого они автоматически добавляются компилятором на этапе компиляции enum-класса.

Добавляем свои методы в enum-класс

У Вас есть возможность добавлять собственные методы как в enum-класс, так и в его элементы:

То же, но с полиморфизмом:

Наследование в enum

С помощью enum в Java можно реализовать иерархию классов, объекты которой создаются в единственном экземпляре и доступны статически. При этом элементы enum могут содержать собственные конструкторы. Приведем пример:

Здесь объявляется перечисление Type с тремя элементами INT, INTEGER и STRING. Компилятор создаст следующие классы и объекты:

Три производных класса будут созданы с полиморфным методом Object parse(String) и конструктором Type(. boolean) При этом объекты классов INT, INTEGER и STRING существуют в единственном экземпляре и доступны статически. В этом можно убедится:

Видно, что компилятор создал класс Type и 3 nested класса, производных от Type.

Декомпилированный enum-class с наследованием

В подтверждение вышесказанному приведем еще результат декомпиляции перечисления Type из примера выше:

Перечисления и параметрический полиморфизм

Дальнейшее изучение

Для более глубокого понимания того, как работают перечисления в Java рекомендую ознакомиться с исходными кодами класса java.lang.Enum, а также воспользоваться декопмилятором Jad для изучения сгенерированного кода. Более того, изучение исходных кодов библиотеки Java абсолютно необходимо для понимания принципов работы многих механизмов в Java и полезно как эталон объектно-ориентированного дизайна.


Дмитрий Пекар, апрель 2009

Если Вам понравилась статья, проголосуйте за нее

Голосов: 171 Голосовать что такое перечисления в java. loading. что такое перечисления в java фото. что такое перечисления в java-loading. картинка что такое перечисления в java. картинка loading. Перечисления появились в пятой версии Java и с тех пор крепко обосновались в наших приложениях. Работа с перечислениями почти не отличается от работы с любыми другими классами в Java. Но есть несколько особенностей, которые вызывают удивление. Каждый раз сталкиваясь с ними, хочется спросить: "Почему так?".

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *