Получить значение Enum путем отражения в Kotlin - PullRequest
0 голосов
/ 13 сентября 2018

Как бы вы переписали следующий код Java в Kotlin?

@SuppressWarnings({ "unchecked", "rawtypes" })
static Object getEnumValue(String enumClassName, String enumValue) throws ClassNotFoundException {
    Class<Enum> enumClz = (Class<Enum>)Class.forName(enumClassName);
    return Enum.valueOf(enumClz, enumValue);
}

Проблемная строка - Enum.valueOf(enumClz, enumValue)

Автоматическое преобразование из IntelliJ IDE / Android Studio дает следующее Enum.valueOf<Enum>(enumClz, enumValue), однако в Котлине нет такого метода Enum.valueOf.

Принудительное использование Kotling java.lang.Enum: java.lang.Enum.valueOf<Enum>(enumClz, enumValue). Ошибка компиляции в универсальной привязке One type argument expected for class Enum<E: Enum<E>>.

Добавление аргумента типа как java.lang.Enum.valueOf<Enum<*>>(enumClz, enumValue) приводит к другой ошибке: Type argument is not within its bounds. Expected: Enum<Enum<*>!>! Found: Enum<*>.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2019

Лучший способ, который я нашел, - это создать интерфейс для перечислений, преобразовав их в типизированные перечисления:

/**
     * Allow to search enums by type
     */
    interface TypedEnum<T> {
        fun value(): T

        companion object {

            /**
             * Get the value of a typed enum
             * @param enumValues array - You can get it with Enum.values()
             * @param enumValue to search
             * @param defaultValue to return if not found
             * @return enum type or default value if not found or first enum value if default value not set
             */
            fun <T, E : TypedEnum<T>> getEnumValue(enumValues: Array<E>, enumValue: T, defaultValue: E? = null): E {
                try {
                    return enumValues.first { it.value()?.equals(enumValue) ?: false}
                } catch (nsee: NoSuchElementException) {
//                    Log.e("TYPED_ENUM", "Exception converting value to enum type: $nsee")
                }
                return defaultValue ?: enumValues.first()
            }
        }

    }

    enum class TypeInt: TypedEnum<Int> {
        TYPE_1 { override fun value() = 1 },
        TYPE_2 { override fun value() = 2 },
        TYPE_3 { override fun value() = 3 },
    }

    enum class TypeString: TypedEnum<String> {
        TYPE_1 { override fun value() = "1" },
        TYPE_2 { override fun value() = "2" },
        TYPE_3 { override fun value() = "3" },
    }

    @Test
    fun getEnumValue_valueExistInt() {

        val value = TypedEnum.getEnumValue(TypeInt.values(), 2)
        assertEquals(TypeInt.TYPE_2, value)
    }

    @Test
    fun getEnumValue_valueExistString() {

        val value = TypedEnum.getEnumValue(TypeString.values(), "2")
        assertEquals(TypeString.TYPE_2, value)
    }

    @Test
    fun getEnumValue_valueNotExist() {

        val value = TypedEnum.getEnumValue(TypeInt.values(), 0)
        assertEquals(TypeInt.TYPE_1, value)
    }

    @Test
    fun getEnumValue_valueNotExistReturnDefault() {

        val value = TypedEnum.getEnumValue(TypeInt.values(), 0, TypeInt.TYPE_3)
        assertEquals(TypeInt.TYPE_3, value)
    }

Это не самый элегантный способ, но он работает.Если я найду лучшее решение, я обновлю это сообщение.

0 голосов
/ 13 сентября 2018

Вы могли бы сделать это следующим образом, конечно, вы, вероятно, должны сделать некоторые дополнительные проверки для переданных параметров, но это должно быть то, что вы ищете:

fun getEnumValue(enumClassName: String, enumValue: String): Any {
    val enumClz = Class.forName(enumClassName).enumConstants as Array<Enum<*>>
    return enumClz.first { it.name == enumValue }
}

Также есть функция enumValueOf , но вам нужно знать фактический тип перечисления, поэтому не уверен, что это поможет, в любом случае, вот как вы могли бы это использовать:

enum class SomeEnum{
    FIRST, SECOND
}
val enumMember = enumValueOf<SomeEnum>("FIRST")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...