Преобразование строки в элемент enum
Только я получаю его как String, а нужно что бы вернул типа enum PriorityType. Как выкрутиться из этой ситуации?
Отслеживать
23.4k 3 3 золотых знака 49 49 серебряных знаков 70 70 бронзовых знаков
задан 10 апр 2015 в 6:06
duddeniska duddeniska
3,958 17 17 золотых знаков 67 67 серебряных знаков 113 113 бронзовых знаков
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Для преобразования строки в элемент enum в каждом enum’е есть метод valueOf :
PriorityType high = PriorityType.valueOf("HIGH");
Этот метод чувствителен к регистру, передаваемая строка должна в точности повторять имя элемента enum’а.
Ещё один вариант, позволяющий кастомизировать строки, на основании которых создаются элементы enum’а. Он строится на основе использования конструктора и реализации своего метода преобразования строки в елемент enum’а:
public enum PriorityType < LOW("LowPrioroty"), MIDDLE("MiddlePrioroty"), HIGH("HighPrioroty"); private String value; private PriorityType(String value) < this.value = value; >public static PriorityType fromString(String value) < if (value != null) < for (PriorityType pt : PriorityType.values()) < if (value.equalsIgnoreCase(pt.value)) < return pt; >> > throw new IllegalArgumentException("No such value"); > > PriorityType low = PriorityType.fromString("lowpriority");
click fraud protection
«перечисление” — жизненно важная функция Java, которая позволяет разработчику хранить данные с гибкими ограничениями. Например, хранение данных внутри или вне класса в соответствии с требованием. В таких случаях использование перечисления и преобразование его в строку в Java помогает хранить и эффективно получать доступ к данным по сравнению с другими подходами.
В этой статье будут обсуждаться методологии преобразования перечисления в строку в Java.
Что такое «перечисление» в Java?
“перечисление” – это сокращенная форма перечисления. Это ключевое слово используется для создания перечисления, и это специальный класс, соответствующий группе констант. Эти константы объявлены внутри «перечисление” и разделяются запятой. Вы также можете объявлять как внутри, так и снаружи класса.
Как преобразовать/преобразовать Enum в строку с помощью Java?
Перечисление можно преобразовать в строку с помощью Java, используя следующие подходы:
Подход 1: преобразование Enum в строку в Java с использованием метода «toString()»
“нанизывать()” используется для получения строкового объекта, который соответствует значению числового объекта и может быть перезаписан. Этот метод можно использовать для простого преобразования значений перечисления в строки, ссылаясь на перечисление.
Синтаксис
Строка в строку ( )
Приведенный выше синтаксис возвращает имя константы перечисления.
Пример
Пройдите приведенный ниже пример:
Примеры пакетов;
Пример публичного класса <
данные перечисления <
АНКАРА, КАНБЕРРА, ЛОНДОН;
>
публичная статическая пустота главная ( Нить [ ] аргументы ) <
System.out.println ( «Строковое значение: » +данные. АНКАРА.toString ( ) ) ;
System.out.println ( «Строковое значение: » +данные. CANBERRA.toString ( ) ) ;
System.out.println ( «Строковое значение: » +данные. ЛОНДОН.toString ( ) ) ;
> >
В приведенных выше строках кода:
- Создайте перечисление с именем «данныеаккумулируя заявленные значения в столицах.
- Обратите внимание, что перечисление здесь объявлено внутри класса.
- Наконец, используйте «точка», чтобы напрямую указывать на значения перечисления и отображать их в строковом представлении с помощью «нанизывать()метод.
Выход

В приведенном выше выводе видно, что значения доступны и отображаются в виде строки.
Подход 2: преобразование/преобразование Enum в строку в Java с использованием метода «name()»
“имя()» класса Enum дает имя константы перечисления, такое же, как объявлено в его (перечислении) объявлении. Этот метод, в отличие от «нанизывать()», является окончательным и не может быть перезаписан.
Синтаксис
общедоступное окончательное имя строки ( )
В приведенном выше синтаксисе «имя()” дает имя этого перечисления.
Пример
Давайте рассмотрим приведенный ниже пример:
Примеры пакетов;
данные перечисления <
АНКАРА, КАНБЕРРА, ЛОНДОН;
>
Пример публичного класса <
публичная статическая пустота главная ( Нить [ ] аргументы ) <
System.out.println ( «Строковое значение: » +данные. АНКАРА.название ( ) ) ;
System.out.println ( «Строковое значение: » +данные. CANBERRA.имя ( ) ) ;
System.out.println ( «Строковое значение: » +данные. ЛОНДОН.название ( ) ) ;
> >
В приведенном выше фрагменте кода:
- Аналогичным образом определите перечисление с именем «данные”, содержащий заданные значения.
- В этом конкретном подходе «перечисление” объявлен вне класса.
- Теперь аналогичным образом обратитесь к содержащимся значениям и извлеките строковое представление, используя связанный «имя()метод.
Выход

Как видите, строковое представление перечисления выбрано правильно.
Заключение
Перечисление, названное перечислением в Java, может быть преобразовано в строку с помощью «нанизывать()«метод» или «имя()метод. Оба этих подхода преобразуют перечисление, указанное внутри и вне класса, в строки соответственно. В этом блоге изложены подходы к преобразованию enum в строку в Java.
Java — конвертировать строку в объект Enum
В Java вы можете использовать Enum valueOf() Чтобы преобразовать String в объект Enum, просмотрите следующий пример:
1. Пример Java Enum
package com.csharpcoderr.whois.utils; public enum WhoisRIR < ARIN("whois.arin.net"), RIPE("whois.ripe.net"), APNIC("whois.apnic.net"), AFRINIC("whois.afrinic.net"), LACNIC("whois.lacnic.net"), JPNIC("whois.nic.ad.jp"), KRNIC("whois.nic.or.kr"), CNNIC("ipwhois.cnnic.cn"), UNKNOWN(""); private String url; WhoisRIR(String url) < this.url = url; >public String url() < return url; >>
2. Проблема
Если задана строка «arin», как преобразовать ее обратно в указанный выше объект Enum?
package com.csharpcoderr.whois.utils; public class TestEnum < public static void main(String[] args) < // Как конвертировать это? WhoisRIR rir = "arin"; >>
3. Решение
Чтобы решить это, вы можете использовать enum valueOf() функция и преобразовать строку в объект Enum.
ЧИТАТЬ ТАКЖЕ: Java — пример асимметричной криптографии
package com.csharpcoderr.whois.utils; import java.util.Locale; public class Test < public static void main(String[] args) < // Решение: использует valueOf () System.out.println(WhoisRIR.valueOf("arin".toUpperCase())); // Рекомендуемое решение: добавить локаль WhoisRIR rir = WhoisRIR.valueOf("ripe".toUpperCase(Locale.ENGLISH)); System.out.println(rir); System.out.println(rir.url()); // Ошибка, нет константы перечисления, чувствительна к регистру //System.out.println(WhoisRIR.valueOf("arin ")); >>
АРИН RIPE whois.ripe.net
Рекомендации
- Oracle — JDK 7 Enum JavaDoc
- Oracle: строка в верхний регистр JavaDoc
- Oracle Doc — Типы Enum
Как использовать enum в Java

Использование в Java в качестве перечислений традиционных примитивных типов проблематично. Java 5 предоставила нам лучшую альтернативу в виде типизированных перечислений ( enum ). В этой статье я познакомлю вас с типизированными перечислениями, покажу вам, как объявить типизированное перечисление и использовать его в операторе switch , а также научу настраивать enum путем добавления данных и методов. И в конце статьи мы изучим класс java.lang.Enum> .
От перечислимых типов к типизированным перечислениям
Перечислимый тип определяется набором связанных констант в качестве его значений. Примерами могут быть: дни недели, стандартные направления компаса север / юг / восток / запад, номиналы монет и типы токенов лексического анализатора.
Перечислимые типы традиционно реализовывались как последовательности целочисленных констант, что демонстрируется следующим набором констант направления:
static final int DIR_NORTH = 0; static final int DIR_WEST = 1; static final int DIR_EAST = 2; static final int DIR_SOUTH = 3;
У такого подхода есть несколько проблем:
- Отсутствует типобезопасность: поскольку константа перечислимого типа является просто целым числом, любое целое число может быть указано там, где требуется константа. Кроме того, над этими константами можно выполнять сложение, вычитание и другие математические операции, например (DIR_NORTH + DIR_EAST) / DIR_SOUTH) , что бессмысленно.
- Отсутствует пространство имен: константы перечисляемого типа должны иметь префикс какого-либо (надеюсь) уникального идентификатора (например, DIR_ ), чтобы предотвратить конфликты с константами другого перечислимого типа.
- Возможность сломать код: поскольку константы перечислимого типа компилируются в class-файлы, где хранятся их реальные значения (в пулах констант), изменение значения константы требует, чтобы эти class-файлы и те class-файлы приложений, которые от них зависят, были пересобраны. В противном случае поведение программы может стать непредсказуемым.
- Недостаток информации: при печати константы выводится ее целочисленное значение. Этот вывод ничего не говорит вам о том, что представляет собой целочисленное значение. Он даже не идентифицирует перечислимый тип, которому принадлежит константа.
Вы можете избежать проблем «отсутствия типобезопасности» и «недостатка информации», используя java.lang.String константы. Например, вы можете указать static final String DIR_NORTH = «NORTH»; . Хотя значение константы более информативно, String константы по-прежнему страдают от «отсутствия пространства имен» и проблем с возможностью сломать код. Кроме того, вы не сможете сравнивать значение строк операторами == и != (которые в случае с объектами сравнивают ссылки).
Эти проблемы заставили разработчиков изобрести альтернативу на основе классов, известную как Typesafe Enum . Этот шаблон широко описывался и подвергался критике . Джошуа Блох представил шаблон в пункте 21 своего Руководства по эффективному языку программирования Java (Addison-Wesley, 2001) и отметил, что в нем есть некоторые проблемы; а именно, что неудобно агрегировать константы Typesafe Enum в наборы, и что константы в качестве перечислений не могут использоваться в операторе switch .
Рассмотрим следующий пример шаблона Typesafe Enum. Класс Suit показывает как вы могли бы использовать альтернативный вариант, основанный на классах для перечисления карточных мастей (трефы, бубны, червы, пика):
public final class Suit // Should not be able to subclass Suit. < public static final Suit CLUBS = new Suit(); public static final Suit DIAMONDS = new Suit(); public static final Suit HEARTS = new Suit(); public static final Suit SPADES = new Suit(); private Suit() <>// Should not be able to introduce additional constants. >
Чтобы использовать этот класс, вы должны ввести переменную типа Suit и присвоить ее одной из Suit -констант следующим образом:
Suit suit = Suit.DIAMONDS;
Затем вы можете проверить suit в таком операторе switch :
switch (suit)
Однако, когда компилятор Java обнаруживает Suit.CLUBS , он сообщает об ошибке, в которой говорится, что требуется константное выражение. Вы можете попытаться решить проблему следующим образом:
switch (suit)
Но в таком случае, когда компилятор обнаруживает CLUBS , он сообщит об ошибке, в которой говорится, что ему не удалось найти символ. И даже если вы поместили Suit в пакет, импортировали пакет и статически импортировали эти константы, компилятор будет жаловаться на то, что он не может преобразовать Suit в int при обнаружении suit в switch(suit) . А в каждом case компилятор сообщит, что требуется константное выражение.
Java не поддерживает шаблон Typesafe Enum с оператором switch . Зато поддерживает enum , который обладает всеми преимуществами этого шаблона и устраняет его проблемы, и enum уже поддерживается в switch .
Объявление enum и использование его в операторе switch
Простое объявление enum в коде Java выглядит так же, как его аналоги в языках C, C ++ и C #:
enum Direction
Здесь используется ключевое слово enum для объявления Direction в качестве типизированного перечисления (особый тип класса), в которое могут быть добавлены произвольные методы и реализованы произвольные интерфейсы. Константы enum NORTH , WEST , EAST и SOUTH являются экземплярами анонимного класса — потомка Direction .
Direction и другие типизированные перечисления являются потомками класса Enum> и наследуют различные методы, в том числе values() , toString() и compareTo() из этого класса. Мы рассмотрим класс Enum позже в этой статье.
Листинг 1 объявляет вышеупомянутое перечисление и использует его в конструкции switch . Он также показывает, как сравнить две константы enum , чтобы определить их порядок в объявлении.
Листинг 1: TEDemo.java(версия 1)
public class TEDemo < enum Direction < NORTH, WEST, EAST, SOUTH >public static void main(String[] args) < for (int i = 0; i < Direction.values().length; i++) < Direction d = Direction.values()[i]; System.out.println(d); switch (d) < case NORTH: System.out.println("Move north"); break; case WEST : System.out.println("Move west"); break; case EAST : System.out.println("Move east"); break; case SOUTH: System.out.println("Move south"); break; default : assert false: "unknown direction"; >> System.out.println(Direction.NORTH.compareTo(Direction.SOUTH)); > >
В листинге 1 объявляется enum Direction и в цикле осуществляется проход по массиву всех его констант-объектов, который возвращается методом values() . Для каждого значения d оператор switch (расширенный для поддержки enum ) выбирает соответствующую константу и выводит сообщение. (При этом ставить префикс перед константой enum , например, NORTH , не требуется.) Наконец, в листинге 1 выполняется сравнение:
Direction.NORTH.compareTo(Direction.SOUTH)
чтобы определить что объявлено раньше NORTH или SOUTH .
Скомпилируйте исходный код следующим образом:
javac TEDemo.java
Запустите скомпилированное приложение следующим образом:
java TEDemo
Вы должны увидеть следующий результат:
NORTH Move north WEST Move west EAST Move east SOUTH Move south -3
Выходные данные показывают, что унаследованный метод toString() возвращает имя константы перечисления, и что NORTH объявлен раньше чем SOUTH .
Добавление данных и поведения в типизированное перечисление
Вы можете добавлять данные (в виде полей) и поведение (в виде методов) в типизированное перечисление. Например, предположим, что вам нужно ввести enum для канадских монет, и этот класс должен предоставить средства для возврата количества пятицентовиков, десятицентовиков, двадцатипятицентовиков или долларов, содержащихся в произвольном количестве центов. В листинге 2 показано, как выполнить эту задачу.
Листинг 2: TEDemo.java (версия 2)
enum Coin < NICKEL(5), // constants must appear first DIME(10), QUARTER(25), DOLLAR(100); // the semicolon is required private final int valueInPennies; Coin(int valueInPennies) < this.valueInPennies = valueInPennies; >int toCoins(int pennies) < return pennies / valueInPennies; >> public class TEDemo < public static void main(String[] args) < if (args.length != 1) < System.err.println("usage: java TEDemo amountInPennies"); return; >int pennies = Integer.parseInt(args[0]); for (int i = 0; i < Coin.values().length; i++) System.out.println(pennies + " pennies contains " + Coin.values()[i].toCoins(pennies) + " " + Coin.values()[i].toString().toLowerCase() + "s"); >>
В листинге 2 сначала объявляется enum Coin . Список параметризованных констант определяет четыре типа монет. Аргумент, передаваемый каждой константе, определяет количество центов в данной монете.
Аргумент, переданный каждой константе, фактически передается конструктору Coin(int valueInPennies) , который сохраняет аргумент в поле экземпляра valuesInPennies . Доступ к этой переменной осуществляется из метода экземпляра toCoins() . На неё делится переданное в метод toCoins() количество центов, после чего возвращается сколько монет, определённых данной Coin константой, содержится в переданном количестве центов.
Теперь вы знаете, что можете объявлять поля, конструкторы и методы экземпляра в типизированном перечислении ( enum ). А значит, enum — это, по сути, особый вид Java-класса.
Метод main() класса TEDemo сначала проверяет, указан ли единственный аргумент командной строки. Этот аргумент преобразуется в целое число путем вызова метода parseInt() класса java.lang.Integer , который преобразует значение строкового аргумента в целое число (или выдает исключение при обнаружении недопустимого ввода). Я расскажу больше об Integer и других классах-обёртках в будущей статье Java 101.
Идём дальше. В методе main() перебираются Coin константы. Поскольку эти константы хранятся в массиве Coin[] , мы получаем длину этого массива через Coin.values().length . В каждой итерации цикла мы получаем доступ к Coin константе через Coin.values()[i] . Для полученной константы вызывается toCoins() и toString() , что еще раз доказывает, что Coin это особый тип класса.
Скомпилируйте исходный код следующим образом:
javac TEDemo.java
Запустите скомпилированное приложение следующим образом:
Java TEDemo 198
Вы должны увидеть следующий результат:
198 pennies contains 39 nickels 198 pennies contains 19 dimes 198 pennies contains 7 quarters 198 pennies contains 1 dollars
Компилятор Java считает enum синтаксическим сахаром. При обнаружении объявления типизированного перечисления он генерирует класс, имя которого указано в объявлении. Этот класс является подклассом абстрактного Enum> класса, который служит базовым классом для всех типов перечислений.
Список формальных параметров класса Enum выглядит ужасно, но смысл не так уж и сложно понять. Например, Coin extends Enum интерпретируется следующим образом:
- Любой подкласс Enum должен предоставлять фактический аргумент типа Enum . Например, для Coin это будет Enum .
- Фактический аргумент типа должен быть подклассом Enum . Например, для Coin это подкласс Enum .
- Подкласс Enum (например, Coin ) должен следовать идиоме, которая предоставляет собственное имя ( Coin ) в качестве фактического аргумента типа.
Исследуйте документацию Java по Enum , и вы обнаружите, что в нём переопределены методы java.lang.Object : clone() , equals() , finalize() , hashCode() и toString() . Все эти переопределённые методы, за исключением toString() , объявлены как final , так что их нельзя переопределить в подклассе:
- clone() переопределяется, чтобы предотвратить клонирование констант, чтобы было не больше одной копии константы; в противном случае константы нельзя было бы сравнивать с помощью == и !=.
- equals() переопределяется для сравнения констант по ссылкам на них. Константы с одинаковыми названиями (==) должны иметь одинаковое содержимое (equals()), а разные названия подразумевают разное содержимое.
- finalize() переопределяется с целью запрета удаления объектов констант.
- hashCode() переопределяется за компанию с equals().
- toString() переопределяется, чтобы вернуть имя константы.
Enum также предоставляет свои собственные методы. В том числе final compareTo() ( Enum реализует интерфейс java.lang.Comparable ), getDeclaringClass() , name() и ordinal() :
- compareTo() сравнивает текущую константу с константой, переданной в качестве аргумента, чтобы увидеть, какая константа предшествует другой константе в перечислении, и возвращает значение, указывающее порядковый номер. Этот метод позволяет отсортировать массив несортированных констант.
- getDeclaringClass() возвращает объект типа java.lang.Class , соответствующий enum текущей константы. Например, в enum Coin < PENNY, NICKEL, DIME, QUARTER>при вызове Coin.PENNY.getDeclaringClass() будет возвращён объект типа Class для Coin (я расскажу об этом в будущей статье Java 101)
- name() возвращает имя константы. Если toString() не переопределен нами для своих целей, он также вернёт имя константы.
- ordinal() возвращает целое число — порядковый номер начиная с нуля, которое определяет позицию константы в enum. Это целое число используется в compareTo() . Например, в предыдущем примере выражение Direction.NORTH.compareTo(Direction.SOUTH) вернуло -3, потому что NORTH имеет порядковый номер 0, а SOUTH имеет порядковый номер 3 и 0–3 (именно так здесь работает compareTo() ) равно -3.
Enum также предоставляет метод public static > T valueOf(Class enumType, String name) для возврата константы из указанного перечисления типов с указанным именем:
- enumType идентифицирует Class объекта перечисления, из которого следует вернуть константу.
- name определяет имя возвращаемой константы.
Например, Coin penny = Enum.valueOf(Coin.class, «PENNY»); присваивает переменной penny значение Coin константы с именем PENNY .
Наконец, Enum документация по Java не включает values() метод, потому что компилятор создает этот метод при создании файла класса enum .
Вам следует выработать привычку использовать типизированные перечисления ( enum ) вместо традиционных перечисляемых типов. Кроме того, возьмите за привычку использовать лямбды вместо анонимных внутренних классов. Про лямбды я расскажу в следующей статье Java 101.