В чем причина 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");
}
Любые идеи относительно того, что я делаю неправильно здесь?
Ответы
Ответ 1
Enum.valueOf()
проверяет только имя константы, поэтому вам нужно передать его "COLUMN_HEADINGS"
вместо "columnHeadings". Ваше свойство name
не имеет ничего общего с внутренностями Enum.
Чтобы ответить на вопросы/проблемы в комментариях:
Enum "встроенный" (неявно объявленный) метод valueOf(String name)
будет искать константу перечисления с таким точным именем. Если вы вводите "columnHeadings", у вас есть (как минимум) три варианта:
- Немного забудь о соглашениях по именованию и просто назови свои константы, так как это имеет смысл:
enum PropName { contents, columnHeadings, ...}
. Это, очевидно, самое удобное.
- Преобразуйте входные данные camelCase в UPPER_SNAKE_CASE перед вызовом
valueOf
, если вы действительно любите соглашения об именах.
- Реализуйте свой собственный метод поиска вместо встроенного
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())