Подтвердить что ты не робот

В чем причина java.lang.IllegalArgumentException: нет класса enum const, хотя итерация через values ​​() работает нормально?

Этот вопрос в основном является расширением моего предыдущего вопроса. Я задал предыдущий вопрос, чтобы убедиться, что константы 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())