您如何在Kotlin中重写以下Java代码?
@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)
,但是Kotlin中没有这样的方法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<*>
。
答案 0 :(得分:0)
我发现最好的方法是为枚举创建接口,并将其转换为类型化的枚举:
/**
* 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)
}
这不是最优雅的方法,但它可以工作。如果我找到更好的解决方案,请更新此消息。