Автор оригинала: Pankaj Kumar.
Перечисление было введено в Java 1.5 как новый тип, поля которого состоят из фиксированного набора констант. Например, мы можем создать направления в виде перечисления Java с фиксированными полями, такими как ВОСТОК, ЗАПАД, СЕВЕР и ЮГ.
Перечисление Java
В этом уроке мы узнаем, как создать перечисление. Мы также рассмотрим преимущества использования перечислений в java и особенности типов перечислений. Мы также научимся использовать Java Перечисление valueOf , перечисление значения , Перечисление и Перечисление с примерами.
Пример перечисления Java
Ключевое слово Java перечисление используется для создания типа перечисления. Давайте взглянем на пример программы перечисления java.
package com.journaldev.enums;
public enum ThreadStates {
START,
RUNNING,
WAITING,
DEAD;
}
В приведенном выше примере состояния потока-это перечисление с фиксированными полями констант “ЗАПУСК”, “ВЫПОЛНЕНИЕ”, “ОЖИДАНИЕ” и “МЕРТВЫЙ”.
Перечисление Java против констант
Теперь давайте посмотрим, насколько перечисление java лучше, чем обычные поля констант в классах Java.
Давайте создадим аналогичный класс констант в java.
package com.journaldev.enums;
public class ThreadStatesConstant {
public static final int START = 1;
public static final int WAITING = 2;
public static final int RUNNING = 3;
public static final int DEAD = 4;
}
Теперь давайте посмотрим, как в java-программе используются как перечисления, так и константы:
/**
* This method shows the benefit of using Enum over Constants
*/
private static void benefitsOfEnumOverConstants() {
//Enum values are fixed
simpleEnumExample(ThreadStates.START);
simpleEnumExample(ThreadStates.WAITING);
simpleEnumExample(ThreadStates.RUNNING);
simpleEnumExample(ThreadStates.DEAD);
simpleEnumExample(null);
simpleConstantsExample(1);
simpleConstantsExample(2);
simpleConstantsExample(3);
simpleConstantsExample(4);
//we can pass any int constant
simpleConstantsExample(5);
}
private static void simpleEnumExample(ThreadStates th) {
if(th == ThreadStates.START) System.out.println("Thread started");
else if (th == ThreadStates.WAITING) System.out.println("Thread is waiting");
else if (th == ThreadStates.RUNNING) System.out.println("Thread is running");
else System.out.println("Thread is dead");
}
private static void simpleConstantsExample(int i) {
if(i == ThreadStatesConstant.START) System.out.println("Thread started");
else if (i == ThreadStatesConstant.WAITING) System.out.println("Thread is waiting");
else if (i == ThreadStatesConstant.RUNNING) System.out.println("Thread is running");
else System.out.println("Thread is dead");
}
Если мы посмотрим на приведенный выше пример, у нас есть два риска с использованием констант, которые решаются перечислением.
- Мы можем передать любую константу int в метод
Пример простых констант, но в simpleEnumExample мы можем передавать только фиксированные значения, поэтому это обеспечивает безопасность типов. - Мы можем изменить значение констант int в
Состояние потока Постояннокласс, но вышеприведенная программа не будет выдавать никаких исключений. Наша программа может работать не так, как ожидалось, но если мы изменим константы перечисления, мы получим ошибку во время компиляции, которая устраняет любую возможность проблем во время выполнения.
Методы перечисления Java
Теперь давайте рассмотрим больше возможностей перечисления java на примере.
package com.journaldev.enums;
import java.io.Closeable;
import java.io.IOException;
/**
* This Enum example shows all the things we can do with Enum types
*
*/
public enum ThreadStatesEnum implements Closeable{
START(1){
@Override
public String toString(){
return "START implementation. Priority="+getPriority();
}
@Override
public String getDetail() {
return "START";
}
},
RUNNING(2){
@Override
public String getDetail() {
return "RUNNING";
}
},
WAITING(3){
@Override
public String getDetail() {
return "WAITING";
}
},
DEAD(4){
@Override
public String getDetail() {
return "DEAD";
}
};
private int priority;
public abstract String getDetail();
//Enum constructors should always be private.
private ThreadStatesEnum(int i){
priority = i;
}
//Enum can have methods
public int getPriority(){
return this.priority;
}
public void setPriority(int p){
this.priority = p;
}
//Enum can override functions
@Override
public String toString(){
return "Default ThreadStatesConstructors implementation. Priority="+getPriority();
}
@Override
public void close() throws IOException {
System.out.println("Close of Enum");
}
}
Java Перечисляет Важные Моменты
Ниже приведены некоторые из важных моментов для перечислений на Java.
- Все перечисления java неявно расширяются
java.lang.Перечислитекласс, который расширяет класс объектов и реализует Сериализуемые и Сопоставимые интерфейсы. Поэтому мы не можем расширить ни один класс в перечислении. - Поскольку перечисление является ключевым словом, мы не можем заканчивать им имя пакета, например
com.journaldev.перечислениене является допустимым именем пакета. - Перечисление может реализовывать интерфейсы . Как и в приведенном выше примере перечисления, он реализует
Закрываемыйинтерфейс. - Конструкторы перечислений всегда являются частными.
- Мы не можем создать экземпляр перечисления с помощью нового оператора.
- Мы можем объявить абстрактные методы в java перечислении, тогда все поля перечисления должны реализовывать абстрактный метод. В приведенном выше примере
get Detail()является абстрактным методом, и все поля перечисления реализовали его. - Мы можем определить метод в перечислении, и поля перечисления также могут переопределять их. Например, метод
toString()определен в перечислении, и поле перечисления START переопределило его. - Поля перечисления Java имеют пространство имен, мы можем использовать поле перечисления только с именем класса, например
Состояния потока.НАЧАЛО - Перечисления можно использовать в операторе switch , мы увидим это в действии в более поздней части этого руководства.
- Мы можем расширить существующее перечисление, не нарушая никаких существующих функций. Например, мы можем добавить новое поле NEW в перечисление Threadstate, не влияя на какие-либо существующие функции.
- Поскольку поля перечисления являются константами, в java рекомендуется писать их печатными буквами и подчеркиванием для пробелов. Например, ВОСТОК, ЗАПАД, EAST_DIRECTION и т.д.
- Константы перечисления неявно статичны и конечны
- Константы перечисления являются окончательными, но их переменную все равно можно изменить. Например, мы можем использовать метод
setPriority()для изменения приоритета констант перечисления. Мы увидим его в использовании в приведенном ниже примере. - Поскольку константы перечисления являются окончательными, мы можем безопасно сравнивать их, используя методы “==” и equals (). И то, и другое приведет к одному и тому же результату.
Java EnumSet, EnumMap, valueOf()
Теперь, когда мы знаем большинство функций перечисления, давайте рассмотрим пример программы перечисления Java. Затем мы узнаем еще некоторые особенности перечисления.
package com.journaldev.enums;
import java.io.IOException;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Set;
public class JavaEnumExamples {
public static void main(String[] args) throws IOException {
usingEnumMethods();
usingEnumValueOf();
usingEnumValues();
usingEnumInSwitch(ThreadStatesEnum.START);
usingEnumInSwitch(ThreadStatesEnum.DEAD);
usingEnumMap();
usingEnumSet();
}
private static void usingEnumSet() {
EnumSet enumSet = EnumSet.allOf(ThreadStatesEnum.class);
for(ThreadStatesEnum tsenum : enumSet){
System.out.println("Using EnumSet, priority = "+tsenum.getPriority());
}
}
private static void usingEnumMap() {
EnumMap enumMap = new EnumMap(ThreadStatesEnum.class);
enumMap.put(ThreadStatesEnum.START, "Thread is started");
enumMap.put(ThreadStatesEnum.RUNNING, "Thread is running");
enumMap.put(ThreadStatesEnum.WAITING, "Thread is waiting");
enumMap.put(ThreadStatesEnum.DEAD, "Thread is dead");
Set keySet = enumMap.keySet();
for(ThreadStatesEnum key : keySet){
System.out.println("key="+key.toString()+":: value="+enumMap.get(key));
}
}
private static void usingEnumInSwitch(ThreadStatesEnum th) {
switch (th){
case START:
System.out.println("START thread");
break;
case WAITING:
System.out.println("WAITING thread");
break;
case RUNNING:
System.out.println("RUNNING thread");
break;
case DEAD:
System.out.println("DEAD thread");
}
}
private static void usingEnumValues() {
ThreadStatesEnum[] thArray = ThreadStatesEnum.values();
for(ThreadStatesEnum th : thArray){
System.out.println(th.toString() + "::priority="+th.getPriority());
}
}
private static void usingEnumValueOf() {
ThreadStatesEnum th = Enum.valueOf(ThreadStatesEnum.class, "START");
System.out.println("th priority="+th.getPriority());
}
private static void usingEnumMethods() throws IOException {
ThreadStatesEnum thc = ThreadStatesEnum.DEAD;
System.out.println("priority is:"+thc.getPriority());
thc = ThreadStatesEnum.DEAD;
System.out.println("Using overriden method."+thc.toString());
thc = ThreadStatesEnum.START;
System.out.println("Using overriden method."+thc.toString());
thc.setPriority(10);
System.out.println("Enum Constant variable changed priority value="+thc.getPriority());
thc.close();
}
}
Прежде чем объяснить другие важные особенности перечисления, давайте посмотрим на результат работы вышеприведенной программы.
priority is:4 Using overriden method.Default ThreadStatesConstructors implementation. Priority=4 Using overriden method.START implementation. Priority=1 Enum Constant variable changed priority value=10 Close of Enum th priority=10 START implementation. Priority=10::priority=10 Default ThreadStatesConstructors implementation. Priority=2::priority=2 Default ThreadStatesConstructors implementation. Priority=3::priority=3 Default ThreadStatesConstructors implementation. Priority=4::priority=4 START thread DEAD thread key=START:: value=Thread is started key=RUNNING:: value=Thread is running key=WAITING:: value=Thread is waiting key=DEAD:: value=Thread is dead Using EnumSet, priority = 10 Using EnumSet, priority = 2 Using EnumSet, priority = 3 Using EnumSet, priority = 4
Важные Моменты
- В
использование методов перечисления()методы показывают, как создать объект перечисления и как мы можем использовать его методы. Он также показывает использование методаsetPriority(int i)для изменения переменной перечисления. использование перечисления valueOf()показывает использованиеjava.util.ПеречислениеЗначение(тип перечисления, имя), с помощью которого мы можем создать объект перечисления из строки. Он создает исключениеIllegalArgumentException, если указанный тип перечисления не имеет константы с указанным именем или указанный объект класса не представляет тип перечисления. Он также выдаетИсключение NullPointerException, если какой-либо из аргументов равен нулю.метод using Enum Values()показывает использование метода values () , который возвращает массив, содержащий все значения перечисления в порядке их объявления. Обратите внимание, что этот метод автоматически генерируется компилятором java для каждого перечисления. Вы не найдете реализацию values() вjava.util.Перечислениекласс.- Метод
использование перечисления в Switch()показывает, как использовать константы перечисления в случае переключателя. использование метода EnumMap()показывает использование java.util.EnumMap , который представлен в платформе коллекций Java 1.5.EnumMap– это реализация карты для использования с ключами типа перечисления. Все ключи в карте перечисления должны принадлежать к одному типу перечисления, который явно или неявно указывается при создании карты. Мы не можем использовать null в качестве ключа для EnumMap, а EnumMap не синхронизирован.использование метода EnumSet()показывает использование java.util.EnumSet , который является реализацией набора для использования с типами перечислений. Все элементы в наборе перечислений должны принадлежать к одному типу перечисления, который явно или неявно указывается при создании набора. Набор перечислений не синхронизирован, и нулевые элементы не допускаются. Он также предоставляет некоторые полезные методы, такие каккопия(Коллекция c),из(E сначала, E... остальное)иДополнение(перечисление s).
Ссылка: Документация Oracle