Для чего нужен enum java
Enum-Всемогущий
Вводная
Предостережение
В этой статье вы не найдете для себя новых технических знаний, откровений, а если Вы жаждете их — то смело переходите к следующей статье. Тем не менее, здесь есть чему удивляться и есть над чем подумать. Технический юмор и филосовские мысли между строк.
Не рассказанная история.
Однажды попадает разработчик в место, где решают судьбу. Время спустя, перед ним появляется образ и спрашивает:
— Кто ты?
— Я, разработчик, звать Иван, — а про себя: Во встрял то.
Голос опять:
— Хочешь туда?. Взгляд на дверь, за которой рай.
— Ага, — робко Иван.
— Чего поведаешь мне?, — спрашивает Голос.
Немного подумав, Иван начинает говорить:
— Есть в java Enum-Всемогущий.
— Как так, Всемогущий? — перебивает Голос с возмущением. — Это только перечисление!
— Ага, — отвечает разраб, Но не только.
— Докажи!
— Enum как гвозди, утильным могёт.
— Во так чудеса, но… Наследника у него нет!
— А это как посмотреть. А кого считать Наследником? Scala? Kotlin?
— Давай пример, не дожидаясь пока разраб завершит свой вопрос
— Да уж, интересные Вы ребята, прогеры — уже улыбаясь, говорит Голос, — Но малова-то будет
Почесав репу, Иван продолжил:
— Enum-то у нас фабрика!
— Не, было уже.
Пришлось, Ивану последний козырь достать:
— Enum-Синглтон, точно!
Выбери свое |
— Джошуа Блох говорит*, что это лучшая реализация Синглтона.
— Ну а ты?
— А что я? Это, это — это синглтон-фабрика, для хранения одного единственного элемента, тить колотить.
Это точка для доступа к массиву для хранения одного единственного элемента, тить колотить.
Немного выводов
Итого получается, что enum можно наделить следующими качествами и свойствами, в зависимости от точки обзора:
Эксперимент
Я решил понять, сколько можно максимально сгенерировать элементов перечислений. Мой собственный ответ и реальность настолько разошлись, что я усомнился в своих знаниях. Прежде чем Вы посмотрите ниже, попытайтесь дать ответ самостоятельно. Упростим, скажите хотя бы порядок? Вот код, который я использовал для генерации класса перечислений (на быструю руку):
Вы уже предположили? Так вот, на семерочке мне удалось сгенерировать всего 2746 элементов перечислений. А дальше вот это:
Но, так как я раскатал губу в 4 этажа, сначала я получил такую ошибку:
Привет! Теме что такое Enums (перечисления) мы посвятим 3 статьи:
Ниже наша первая статья. Приятного прочтения.
Что такое Enums
«Зима, весна, лето, осень?»
В жизни часто у нас есть выбор из ограниченного количества вариантов. Это можно сравнить с «меню», из которого мы можем выбирать.
Как представить такое «меню» в коде? Как говорится, лучше один раз увидеть:
Вот мы и создали наш первый Enum! Выглядит просто, правда?
Давайте обратим внимание на ключевые моменты:
Если же enum будет «внутри» класса, он может быть объявлен private:
В конце мы написали точку с запятой.
Пример 1
Мы уже описывали один enum выше. Давайте создадим такой же, только для наглядности назовем его не myEnum, а Seasons(«времена года»):
Что такое перечисления в Java? (java enum)
Перечисление или java enum – это набор именованных констант, который помогает в определении своих собственных типов данных. Когда вы можете определить тип переменных в программе, становится легко их определить.
Перечисление – это в основном список именованных констант. В Java это определяет тип класса. Он может иметь конструкторы, методы и переменные экземпляра. Он создается с помощью ключевого слова enum. По умолчанию каждая константа перечисления имеет вид.
Хотя перечисление определяет тип класса и имеет конструкторы, вам не нужно создавать экземпляр перечисления с помощью новой переменной. Переменные перечисления используются и объявляются так же, как переменные примитива.
Объявление enum может быть сделано вне Класса или внутри Класса. Но мы не можем объявить Enum внутри метода. Давайте рассмотрим небольшой пример, чтобы понять его декларацию.
1. Объявление перечисления в Java вне класса
2. Объявление перечисления в Java внутри класса
Первая строка внутри типа enum должна быть списком констант. Затем вы можете использовать методы, переменные и конструктор. По сути, enum представляет группу переменных и констант.
Перечисление с использованием оператора Switch
Значение перечисления также может использоваться для управления оператором switch. Необходимо, чтобы все операторы case использовали константы из того же перечисления, что и оператор switch. Ниже пример демонстрирует то же самое.
Values() и метод ValueOf()
Values(): при создании enum компилятор Java внутренне добавляет метод values(). Этот метод возвращает массив, содержащий все значения перечисления.
ValueOf(): этот метод используется для возврата константы перечисления, значение которой равно строке, переданной в качестве аргумента при вызове этого метода.
Теперь давайте напишем программу, чтобы понять эти методы более подробно.
Вот как вы можете использовать метод Values(), чтобы вернуть массив, содержащий все перечисления, присутствующие в методе, и Valueof(), чтобы вернуть константу перечисления.
Перечисление с помощью конструктора, переменной экземпляра и метода
По сути, перечисление может содержать конструктор и выполняется отдельно для каждой константы перечисления во время загрузки класса перечисления. Кроме того, перечисление может создавать конкретные методы.
Здесь, как только мы объявляем переменную enum(), конструктор вызывается один раз, и он инициализирует параметр age для каждой константы перечисления значениями, указанными в скобках.
Что нужно знать?
1). Перечисления в Java являются типобезопасными и имеют собственное пространство имен. Это означает, что ваше перечисление будет иметь тип, например «Валюта» в приведенном ниже примере, и вы не можете присвоить какое-либо значение, кроме указанного в константах перечисления.
2). Enum в Java – это ссылочные типы, такие как класс или интерфейс, и вы можете определить конструктор, методы и переменные внутри, что делает его более мощным, чем Enum в C и C ++, как показано в следующем примере.
3). Вы можете указать значения констант перечисления во время создания, как показано в примере ниже:
Но для этого вам необходимо определить переменную-член и конструктор, потому что PENNY (1) фактически вызывает конструктор, который принимает значение int, см. Пример ниже.
Конструктор должен быть закрытым, любой другой модификатор доступа приведет к ошибке компиляции. Теперь, чтобы получить значение, связанное с каждой монетой, вы можете определить общедоступный метод getValue() внутри перечисления Java, как любой обычный класс. Кроме того, точка с запятой в первой строке не обязательна.
4) Константы перечисления неявно статичны и окончательны и не могут быть изменены после создания. Например, приведенный ниже код приведет к ошибке компиляции:
Последнее поле EnumExamples.Currency.PENNY нельзя переназначить.
5) Может использоваться в качестве аргумента в операторе switch и с «case:», например, с примитивным типом int или char. Эта особенность делает их очень полезными для операций переключения. Давайте посмотрим, как использовать enum внутри оператора switch:
Поскольку константы, определенные внутри Enum, являются окончательными, вы можете безопасно сравнивать их, используя «==», оператор равенства, как показано в следующем примере:
Сравнение объектов с использованием оператора == не рекомендуется. Всегда используйте метод equals() или compareTo() для сравнения объектов.
7). Компилятор Java автоматически генерирует метод static values() для каждого перечисления. Метод Values() возвращает массив констант Enum в том же порядке, в котором они перечислены, и вы можете использовать values() для перебора значений, как показано в примере ниже:
8). Он также может переопределять методы. Давайте посмотрим на пример переопределения метода toString() внутри Enum, чтобы предоставить содержательное описание для констант перечислений.
А вот как это выглядит при отображении:
9). Два новых класса коллекции EnumMap и EnumSet добавлены в пакет коллекции для поддержки. Эти классы представляют собой высокопроизводительную реализацию интерфейса Map and Set в Java, и мы должны использовать их всякий раз, когда есть возможность.
EnumSet не имеет общедоступного конструктора, вместо этого он предоставляет фабричные методы для создания экземпляра, например. EnumSet.of() методы. Этот дизайн позволяет EnumSet внутренне выбирать между двумя различными реализациями в зависимости от размера констант.
Если Enum имеет менее 64 констант, чем EnumSet использует класс RegularEnumSet, который внутренне использует длинную переменную для хранения этих 64 констант, а если Enum имеет больше ключей, чем 64, то он использует JumboEnumSet.
10). Вы не можете создать экземпляр перечислений с помощью оператора new в Java, потому что конструктор может быть только частным, а константы Enums могут быть созданы только внутри него самого.
11). Экземпляр создается, когда какие-либо константы Enum сначала вызываются или упоминаются в коде.
12). Может реализовать интерфейс и переопределить любой метод, такой как обычный класс. Также стоит отметить, что Enum в Java неявно реализует как Serializable, так и Comparable интерфейс. Давайте посмотрим и пример того, как реализовать интерфейс:
13). Вы можете определить абстрактные методы внутри Enum, а также можете предоставить другую реализацию для разных экземпляров. Давайте посмотрим на пример использования абстрактного метода внутри.
В этом примере, поскольку каждая монета будет иметь разный цвет, мы сделали метод color() абстрактным и позволили каждому экземпляру Enum определять свой собственный цвет. Вы можете получить цвет любой монеты, просто вызвав метод color(), как показано в примере ниже:
Java Enum перечисления с примерами
Enums – это специальный тип, используемый для определения коллекций констант. Точнее, тип перечисления – это особый вид класса Java, который может содержать константы, методы и т. д. Были добавлены в Java 5. Это руководство объясняет, как создавать и использовать их.
Пример Enum
Вот простой пример:
Обратите внимание на ключевое слово enum, которое используется вместо класса или интерфейса. Оно сообщает компилятору, что это определение типа является перечислением.
Вы можете сослаться на константы в перечислении выше, как это:
Обратите внимание, что переменная уровня имеет тип Level, который является типом перечисления, определенным в примере выше. Переменная уровня может принимать одну из констант уровня Level в качестве значения (HIGH, MEDIUM или LOW). В этом случае уровень установлен на HIGH.
В заявлениях if
Поскольку перечисления являются константами, вам часто приходится сравнивать переменную, указывающую на константу перечисления, с возможными константами в типе перечисления:
Этот код сравнивает переменную уровня с каждой из возможных констант перечисления в перечислении уровня.
Если одно из значений встречается чаще, чем другие, проверка этого значения в первом операторе if приведет к лучшей производительности, так как выполняется меньше сравнений в среднем. Это не большая разница, если только сравнения не выполняются.
В выражениях
Если ваши типы перечислений содержат много констант, и вам нужно проверить переменную по значениям, как показано в предыдущем разделе, использование оператора переключения switch может быть хорошей идеей:
Замените … на код, который нужно выполнить, если переменная уровня соответствует заданному значению константы уровня. Код может быть простой операцией, вызовом метода и т. д.
Итерации
Вы можете получить массив всех возможных значений типа enum, вызвав его метод static values(). Все типы перечислений получают статический метод values() автоматически компилятором. Вот пример итерации всех значений:
Выполнение этого кода распечатало бы все значения:
Обратите внимание, как распечатываются имена самих констант. Это одна из областей, где перечисления отличаются от статических конечных констант.
toString()
Класс enum автоматически получает метод toString() в классе при компиляции. Он возвращает строковое значение имени данного экземпляра перечисления:
Значением переменной levelText после выполнения вышеприведенного оператора будет текст HIGH.
Printing
Если вы печатаете перечисление, вот так:
Затем метод toString() будет вызван и значение, которое будет напечатано, является текстовым именем экземпляра enum. Другими словами, в приведенном выше примере текст HIGH был бы напечатан.
valueOf()
Класс enum автоматически получает статический метод valueOf() в классе при компиляции. Его можно использовать для получения экземпляра класса для данного значения String:
Переменная уровня будет указывать на Level.HIGH после выполнения этой строки.
Fields
Вы можете добавить поля в перечисление. Таким образом, каждое значение константы enum получает их. Значения полей должны быть предоставлены конструктору перечисления при определении констант:
Обратите внимание, что перечисление в приведенном выше примере имеет конструктор, который принимает int. Он устанавливает поле int. Когда постоянные значения перечисления определены, значение int передается в конструктор Java.
Конструктор enum должен быть либо закрытым, либо областью действия пакета (по умолчанию). Вы не можете использовать публичные или защищенные.
Методы
Вы также можете добавлять методы:
Вы вызываете метод через ссылку на одно из значений констант:
Этот код выведет значение 3, которое является значением поля levelCode для константы перечисления HIGH.
Вы не ограничены простыми методами получения и установки. Можете создавать методы, которые производят вычисления на основе значений полей константы перечисления. Если поля не объявлены как final, вправе изменить значения полей (хотя это может быть не очень хорошей идеей, учитывая, что перечисления должны быть константами).
Abstract методы
Для класса enum также могут быть абстрактные методы. Если у класса есть абстрактный метод, то каждый экземпляр класса должен его реализовывать:
Обратите внимание на объявление абстрактного метода внизу класса enum. Каждый экземпляр enum (каждая константа) определяет собственную реализацию этого метода. Его использование полезно, когда нужна отдельная реализация метода для каждого экземпляра перечисления.
Реализация интерфейса
Enum может реализовать интерфейс, если чувствуете, что это имеет смысл в вашей ситуации:
Это метод getDescription(), который приходит из интерфейса MyInterface.
Реализация интерфейса с Enum может использоваться для реализации набора различных констант Comparator, которые применяются для сортировки коллекций объектов.
EnumSet
Специальная реализация Java Set под названием EnumSet, которая может хранить перечисления более эффективно, чем стандартные реализации:
После создания вы можете использовать EnumSet, как и любой другой набор.
EnumMap
Специальная реализация Java Map, которая может использовать экземпляры перечисления в качестве ключей:
Как использовать enum в Java
Джефф Фризен, JavaWorld | 12 ноября 2020
От перечислимых типов к типизированным перечислениям
Перечислимый тип определяется набором связанных констант в качестве его значений. Примерами могут быть: дни недели, стандартные направления компаса север / юг / восток / запад, номиналы монет и типы токенов лексического анализатора.
Перечислимые типы традиционно реализовывались как последовательности целочисленных констант, что демонстрируется следующим набором констант направления:
У такого подхода есть несколько проблем:
Рассмотрим следующий пример шаблона Typesafe Enum. Класс Suit показывает как вы могли бы использовать альтернативный вариант, основанный на классах для перечисления карточных мастей (трефы, бубны, червы, пика):
Затем вы можете проверить suit в таком операторе switch :
Объявление enum и использование его в операторе switch
Простое объявление enum в коде Java выглядит так же, как его аналоги в языках C, C ++ и C #:
Листинг 1: TEDemo.java(версия 1)
Скомпилируйте исходный код следующим образом:
Запустите скомпилированное приложение следующим образом:
Вы должны увидеть следующий результат:
Добавление данных и поведения в типизированное перечисление
Вы можете добавлять данные (в виде полей) и поведение (в виде методов) в типизированное перечисление. Например, предположим, что вам нужно ввести enum для канадских монет, и этот класс должен предоставить средства для возврата количества пятицентовиков, десятицентовиков, двадцатипятицентовиков или долларов, содержащихся в произвольном количестве центов. В листинге 2 показано, как выполнить эту задачу.
Листинг 2: TEDemo.java (версия 2)
Теперь вы знаете, что можете объявлять поля, конструкторы и методы экземпляра в типизированном перечислении ( enum ). А значит, enum — это, по сути, особый вид Java-класса.
Скомпилируйте исходный код следующим образом:
Запустите скомпилированное приложение следующим образом:
Вы должны увидеть следующий результат:
Компилятор Java считает enum синтаксическим сахаром. При обнаружении объявления типизированного перечисления он генерирует класс, имя которого указано в объявлении. Этот класс является подклассом абстрактного Enum > класса, который служит базовым классом для всех типов перечислений.
Список формальных параметров класса Enum выглядит ужасно, но смысл не так уж и сложно понять. Например, Coin extends Enum интерпретируется следующим образом:
Enum также предоставляет метод public static > T valueOf(Class enumType, String name) для возврата константы из указанного перечисления типов с указанным именем:
Вам следует выработать привычку использовать типизированные перечисления ( enum ) вместо традиционных перечисляемых типов. Кроме того, возьмите за привычку использовать лямбды вместо анонимных внутренних классов. Про лямбды я расскажу в следующей статье Java 101.
Перевод Академии Progwards