No enum constant ошибка

Pre-requisite :  Java : Enumeration Handling Below is example of enumeration by using all implicit methods of enumeration.Here used wrong value of enumeration as “Saturday” while u…

Pre-requisite :  Java : Enumeration Handling

Below is example of enumeration by using all implicit methods of enumeration.
Here used wrong value of enumeration as “Saturday” while using month name here that’s why causing this issue.

package enm;

public class EnumTest {

	enum Month{JANNUARY,FEBRUARY,MARCH,APRIL,MAY,JUNE,JULY,AUGUST,SEPTEMBER,OCTOBER,NOVEMBER,DECEMBER};
	enum MonthDetail{
		JANNUARY("January",1),
		FEBRUARY("February",2),
		MARCH("March",3),
		APRIL("April",4),
		MAY("May",5),
		JUNE("June",6),
		JULY("July",7),
		AUGUST("August",8),
		SEPTEMBER("September",9),
		OCTOBER("October",10),
		NOVEMBER("November",11),
		DECEMBER("December",12);

		public String monthName="";
		public int index;

		//Constructor will always private
		private MonthDetail(String monthName,int index)
		{
			this.monthName=monthName;
			this.index=index;
		}
		//Method
		public void showMonthDetail()
		{
			System.out.println(this.index +" : "+this.monthName);
		}
	};
	public static void main(String[] args) {
		for(Month month:Month.values())
		{
	    //Add one because by default enum indexing start from 0
		System.out.println((month.ordinal()+1) +" : "+month.name());
		}
		//Every enum Class provide values method to get list of enums
		for(MonthDetail monthDetail:MonthDetail.values())
		{
			monthDetail.showMonthDetail();
		}

		try
		{
		MonthDetail mnth=MonthDetail.valueOf("Saturday");
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}

	}

}

Output

1 : JANNUARY
2 : FEBRUARY
3 : MARCH
4 : APRIL
5 : MAY
6 : JUNE
7 : JULY
8 : AUGUST
9 : SEPTEMBER
10 : OCTOBER
11 : NOVEMBER
12 : DECEMBER
1 : January
2 : February
3 : March
4 : April
5 : May
6 : June
7 : July
8 : August
9 : September
10 : October
11 : November
12 : December
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant enm.EnumTest.MonthDetail.Saturday
    at java.lang.Enum.valueOf(Enum.java:238)
    at enm.EnumTest$MonthDetail.valueOf(EnumTest.java:1)
    at enm.EnumTest.main(EnumTest.java:49)

Solutions:
Always use valid constant values to resolve this issue and while trying to call this enum.valueOf() method always handle exception so that any exception happen then your program will not terminate.

try {
 MonthDetail mnth=MonthDetail.valueOf("August");
} catch(Exception ex) {
ex.printStackTrace();
}

To learn more on Enumeration follow below link: Java : Enumeration Handling

“Learn From Others Experience»

Данная статья:

  • написана командой Vertex Academy. Надеемся, что она Вам будет полезна. Приятного прочтения!
  • это одна из статей из нашего «Самоучителя по Java» 
  • Данная статья предполагает, что Вы уже хорошо знаете ООП.

В предыдущей статье (Урок 66: Перечисления Enum в Java) мы рассмотрели что такое Enum в Java. Абстрактный класс Enum появился в 5-й версии Java. Теперь, благодаря абстрактному классу Enum мы можем быстро и легко создавать перечисления без написания повторяющегося кода.

В этой статье мы рассмотрим на конкретных примерах следующее:

1. К Enum можно применять методы:

  • name() — возвращает имя
  • ordinal() — возвращает порядковый номер
  • equals()
  • hashCode()
  • toString()
  • finalize()
  • clone()
  • values()
  • valueOf()

2. Enum реализовывает интерфейс Comparable

3. Enum реализовывает интерфейс Serializable


Иииииии сразу в бой 🙂 Создадим простой enum Color

enum Color {

    RED, GREEN, BLUE

}

Методы name() и ordinal()

У каждого enum есть имя и порядковый номер. Получить их можно с помощью методов name() и ordinal()

System.out.println(Color.RED.name()); //output: RED

System.out.println(Color.RED.ordinal()); //output: 0

Посмотрим как это реализовано в классе Enum

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

public abstract class Enum<E extends java.lang.Enum<E>>

        implements Comparable<E>, Serializable {

    private final String name;

    public final String name() {

        return name;

    }

    private final int ordinal;

    public final int ordinal() {

        return ordinal;

    }

    protected Enum(String name, int ordinal) {

        this.name = name;

        this.ordinal = ordinal;

    }

....

}

Пояснения:

  • Конструктор невидим для разработчиков, но используется самой Java для корректной работы перечислений.

Возникает вопрос, а где же ключевое слово extends возле декларации перечисления Color? Все дело в ключевом слове enum, именно оно даёт понять программе, что вы хотите не просто класс, а именно перечисление, что и дает Вам уйму возможностей.

Методы equals(), hashcode(), toString(), finalize() и clone()

Enum переопределяет базовые методы класса Object. Так что их можно использовать сразу же в наших перечислениях.

Пример 1: equals()

boolean isEqualToItself = Color.RED.equals(Color.RED);

boolean isEqualToDifferentColor = Color.RED.equals(Color.GREEN);

System.out.println(isEqualToItself); //output: true

System.out.println(isEqualToDifferentColor);//output: false

Пример 2:  hashCode()

int hashOfRed = Color.RED.hashCode();

int hashOfGreen = Color.GREEN.hashCode();

System.out.println(hashOfRed); //output would be different every time: 366712642

System.out.println(hashOfGreen); //output would be different every time: 1829164700

Поскольку мы использовали hashCode(), каждый раз будет выводиться разное значение, сгенерированное автоматически. Когда мы запускали код, получили числа 366712642 и 1829164700. Вы наверняка получите другие числа.

Пример 3: toString()

String red = Color.RED.toString();

System.out.println(red); //output: RED

Посмотрим как они реализованы в классе Enum

public String toString() {

    return name;

}

public final boolean equals(Object other) {

    return this==other;

}

public final int hashCode() {

    return super.hashCode();

}

Пояснения:

  • метод toString() возвращает имя значения перечисления. Назвали значение WHITE, это же значение и получим при вызове toString() или name();
  • метод equals() сравнивает значения перечислений по ссылкам. Почему? Потому, что значения в перечислениях являются константными (уникальными), существует всего один экземпляр цвета RED, один цвета GREEN и один BLUE, значит ссылка на этот экземпляр будет всего одна, значит их можно сравнивать с помощью ==. Вы можете сами убедиться в этом, написав Color.RED == Color.RED или Color.GREEN == COLOR.BLUE;
  • метод hashCode() использует стандартную реализацию из класса Object.

Пример 4: finalize(), clone()

protected final void finalize() { }

protected final Object clone() throws CloneNotSupportedException {

    throw new CloneNotSupportedException();

}

Пояснения:

  • метод finalize() пустой, а это значит, что не нужно закрывать «ресурсы» перед сборщиком мусора.  Мы говорим о тех «ресурсах», которые используются в try-with-resources. Да и вообще метод finalize() пережиток прошлых лет и в Java 9 данный метод уже помечен как @Deprecated (устаревший метод, который уберут в последующих реализациях);
  • метод clone() мы можем вызвать только внутри самого перечисления т.к. он помечен ключевым словом protected. Но даже если мы попытаемся сделать это, то ничего мы не получим, кроме CloneNotSupportedException. Нужно это для того чтобы нельзя было создать несколько экземпляров одного и того же перечисления. Ведь в реальной жизни у нас нет двух цифр «1», нет двух значений скорости света, так и с перечислениями.

Метод values() — позволяет получить массив всех значений Enum

Сделать это можно с помощью метода values()

Color[] colors = Color.values();

System.out.println(Arrays.toString(colors)); //output: [RED, GREEN, BLUE]

Посмотрим на реализацию метода values() в классе Enum

public static E[] values();

Пояснения:

  • полной реализации метода в классе Enum нет, так как он синтетический (искусственно добавляется во время компиляции). Из документации узнаем, что метод просто возвращает массив всех значений перечисления в порядке их объявления.

Метод valueOf() — позволяет получить значения перечисления по его строковому представлению

Для получения значение перечисления по его строковому представлению у Enums есть метод valueOf(). Посмотрим на его использование

System.out.println(Color.valueOf(«RED»).ordinal()); //output: 0

Если же такого значения в перечислении нет, то мы получим IllegalStateException

Color.valueOf(«BLACK»); //output: java.lang.IllegalArgumentException: No enum constant Color.BLACK

Посмотрим на реализацию метода valueOf() в классе Enum

public static E valueOf(String name);

Пояснения:

  • как и в случае с values() этот метод тоже синтетический и поэтому полной реализации данного метода в классе Enum нет. В официальной документации написано, что метод просто возвращает значение перечисления по его строковому представлению. Проверка строгая, поэтому никаких пробелов вначале, в конце или между буквами не должно быть.

Есть еще один способ получить значение перечисления

System.out.println(Enum.valueOf(Color.class, «BLUE»).ordinal()); //output: 2

но он является менее распространённым.

Рассмотрим его подробнее:

public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {

    T result = enumType.enumConstantDirectory().get(name);

    if (result != null)

        return result;

    if (name == null)

        throw new NullPointerException(«Name is null»);

    throw new IllegalArgumentException(

        «No enum constant « + enumType.getCanonicalName() + «.» + name);

}

Пояснения:

  • метод enumConstantDirectory() возвращает Map, где ключ — строковое значение перечисления, а значение — реальное значение перечисления;
  • если мы нашли нужное значение в Map — возвращаем его;
  • если мы передали null в метод valueOf() — обратно получим NullPointerException;
  • если же значения, которое мы указали в valueOf() нет — мы получим IllegalArgumentException.

Enum реализовывает интерфейс Comparable

Что такое интерфейс Comparable мы рассматривали в статье «Интерфейсы Comparable и Comparator».

Зачем же Enum реализовывает интерфейс Comparable? Сделано это для того, чтобы перечисления можно было сравнивать друг с другом при сортировке. При этом сравнение происходит по ordinal() перечисления. Вспомним порядок объявления значений в Color

enum Color {

    RED, GREEN, BLUE

}

Теперь посмотрим на сравнение элементов перечисления с помощью метода compareTo()

System.out.println(Color.GREEN.compareTo(Color.RED)); //output: 1

System.out.println(Color.GREEN.compareTo(Color.GREEN)); //output: 0

System.out.println(Color.GREEN.compareTo(Color.BLUE)); //output: -1

System.out.println(Color.RED.compareTo(Color.BLUE)); //output: -2

Результат показывает как располагаются значения перечисления относительно друг друга:

  • Число означает, что значение GREEN находится правее на одну позицию от значения RED
  • Число означает, что значение GREEN равно само себе
  • Число -1 означает, что значение GREEN находится левее от значения BLUE на одну позицию
  • Число -2 означает, что значение RED находится левее от значения BLUE на две позиции

А теперь посмотрим на использование в коллекции List

List<ColorEnum> colors = new ArrayList<>(List.of(Color.GREEN, Color.RED, Color.BLUE));

System.out.println(colors); //output: [GREEN, RED, BLUE]

Collections.sort(colors);

System.out.println(colors); //output: [RED, GREEN, BLUE]

Метод Collections.sort(colors) отсортировал список colors благодаря тому, что Enum реализовывают интерфейс Comparable. Посмотрим на реализацию метода compareTo() в классе Enum

public final int compareTo(E o) {

    Enum<?> other = (Enum<?>)o;

    Enum<E> self = this;

    if (self.getClass() != other.getClass() &&

        self.getDeclaringClass() != other.getDeclaringClass())

        throw new ClassCastException();

    return self.ordinal other.ordinal;

}

Пояснения:

  • сравнивать перечисления можно только между своими типами. Нельзя сравнивать перечисления типа Color с перечислением типа Car. Мало того, что компилятор не даст вам это сделать с помощью своих подсказок так еще и в самом методе есть проверка на тип класса перечислений.

Enum реализовывает интерфейс Serializable

Но как и в случае с clone() воспользоваться мы им не можем

private void readObject(ObjectInputStream in) throws IOException,

    ClassNotFoundException {

    throw new InvalidObjectException(«can’t deserialize enum»);

}

private void readObjectNoData() throws ObjectStreamException {

    throw new InvalidObjectException(«can’t deserialize enum»);

}

Пояснения:

  • причина того, что эти методы приватные да и к тому же бросают исключения при их вызове так же, что и в случае с clone(). Если бы эта возможность была открыта, тогда легко можно было бы сохранить перечисление в файл, затем считать его обратно и получить на выходе два экземпляра одного значения перечисления. Этот как два значения числа «1»;

На этом урок заканчивается

В следующей статье мы разберем:

  • конструкторы, переменные и собственные методы в перечислениях;
  • специальные коллекции для перечислений.

3-ю статью по Enum можно прочитать здесь.

Спасибо, что были с нами! 🙂


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

Этот вопрос в основном является расширением моего предыдущего вопроса. Я задал предыдущий вопрос, чтобы убедиться, что константы Enum заполняются, когда класс загружается. Вот мой класс снова с добавлением простого метода getByName:

public enum PropName {

  CONTENTS("contents"),
  USE_QUOTES("useQuotes"),
  ONKEYDOWN("onkeydown"),
  BROWSER_ENTIRE_TABLE("browseEntireTable"),
  COLUMN_HEADINGS("columnHeadings"),
  PAGE_SIZE("pageSize"),
  POPUP_TITLE("popupTitle"),
  FILTER_COL("filterCol"),
  SQL_SELECT("sqlSelect"),
  ;

  private String name;

  private PropName(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public static PropName getByName(String name){
    return   PropName.valueOf(name);
  }
}

Вызов метода getByName("columnHeadings") вызывает java.lang.IllegalArgumentException: No enum const class labware.web.component.limsgrid.PropName.columnHeadings, но если я заменил этот метод на следующий код, он просто работает.

 public static PropName getByName(String name){
    for(PropName prop : values()){
      if(prop.getName().equals(name)){
        return prop;
      }
    }

    throw new IllegalArgumentException(name + " is not a valid PropName");
  }

Любые идеи относительно того, что я делаю неправильно здесь?

4b9b3361

Ответ 1

Enum.valueOf() проверяет только имя константы, поэтому вам нужно передать его "COLUMN_HEADINGS" вместо «columnHeadings». Ваше свойство name не имеет ничего общего с внутренностями Enum.


Чтобы ответить на вопросы/проблемы в комментариях:

Enum «встроенный» (неявно объявленный) метод valueOf(String name) будет искать константу перечисления с таким точным именем. Если вы вводите «columnHeadings», у вас есть (как минимум) три варианта:

  1. Немного забудь о соглашениях по именованию и просто назови свои константы, так как это имеет смысл: enum PropName { contents, columnHeadings, ...}. Это, очевидно, самое удобное.
  2. Преобразуйте входные данные camelCase в UPPER_SNAKE_CASE перед вызовом valueOf, если вы действительно любите соглашения об именах.
  3. Реализуйте свой собственный метод поиска вместо встроенного valueOf, чтобы найти соответствующую константу для входа. Это наиболее целесообразно, если существует несколько возможных отображений для одного и того же набора констант.

Ответ 2

Это потому, что вы определили свою собственную версию name для вашего перечисления, а getByName не использует это.

getByName("COLUMN_HEADINGS"), вероятно, будет работать.

Ответ 3

Вместо определения: COLUMN_HEADINGS("columnHeadings")

Попробуйте определить его как: COLUMNHEADINGS("columnHeadings")

Затем, когда вы вызываете getByName(String name) method, вызовите его с строкой с верхним острием следующим образом: getByName(myStringVariable.toUpperCase())

У меня была такая же проблема, как и вы, и это сработало для меня.

Ответ 4

У меня была проблема с анализом enum, когда я пытался передать Nullable Enum, который мы получили из Backend.
Конечно, это работало, когда мы получали значение, но это было проблемой, когда ноль появлялся.

java.lang.IllegalArgumentException: нет константы перечисления

Также проблема заключалась в том, что когда мы в момент чтения Parcelize пишем несколько коротких if.

Мое решение для этого было

1.Создать сопутствующий объект с помощью метода синтаксического анализа.

enum class CarsType {
    @Json(name = "SMALL")
    SMALL,
    @Json(name = "BIG")
    BIG;

    companion object {
        fun nullableValueOf(name: String?) = when (name) {
            null -> null
            else -> valueOf(name)
        }
    }
}

2. В Parcerable read place используйте это так

data class CarData(
    val carId: String? = null,
    val carType: CarsType?,
    val data: String?
) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readString(),
        CarsType.nullableValueOf(parcel.readString()),
        parcel.readString())

Понравилась статья? Поделить с друзьями:
  • No drq victoria как исправить
  • No dns rpc connectivity error or non microsoft dns server is running
  • No dmarc record found как исправить
  • No displays found in the registry как исправить
  • No directx 11 compatible display adapter found error code 1206 anno 2205