12

I have the following code in java:

Enum getEnumValue(Class<?> enumClass, String value) {
    return Enum.valueOf((Class<Enum>) enumClass, value);
}

How to rewrite this in Kotlin?

Update

enumValueOf<>() function is not applicable in this case because I don't know the actual type parameter, I only have a Class<?> object with unknown type (Class<*> in kotlin) and a name string. The Class is known to be enum: Class.isEnum returns true. Using these two inputs, the java code above allows to obtain the value of the enum with a raw type. That's just what I need because I'm not interested in the specific type of the enum. But I can't figure out how to get the same result in kotlin.

Eugene
  • 374
  • 1
  • 2
  • 10

4 Answers4

13

Here's a pure Kotlin version:

@Suppress("UNCHECKED_CAST")
fun getEnumValue(enumClass: Class<*>, value: String): Enum<*> {
    val enumConstants = enumClass.enumConstants as Array<out Enum<*>>
    return enumConstants.first { it.name == value }
}

Note that it's not as efficient as the Java version. java.lang.Enum.valueOf uses a cached data structure while this version needs to create a new array to iterate over. Also this version is O(n) wheras the Java version is O(1) as it uses a dictionary under the hood.

There is an open issue in the Kotlin bug tracker to support the same code as in Java which is scheduled for 1.3.

Here's a really ugly hack to workaround the generic type issue:

private enum class Hack

fun getEnumValue(enumClass: Class<*>, value: String): Enum<*> {
    return helper<Hack>(enumClass, value)
}

private fun <T : Enum<T>>helper(enumClass: Class<*>, value: String): Enum<*> {
    return java.lang.Enum.valueOf(enumClass as Class<T>, value)
}

A quick test shows that it's working but I wouldn't rely on it.


If the generic type is available, you can use the built-in function enumValueOf (see also http://kotlinlang.org/docs/reference/enum-classes.html#working-with-enum-constants):

enum class Color {
    Red, Green, Blue
}

enumValueOf<Color>("Red")
Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148
4

You can use below Kotlin code in your class for java code:

Kotlin function code:

private inline fun <reified T : kotlin.Enum<T>> getEnumValue(type: String?): T? {
    return java.lang.Enum.valueOf(T::class.java, type)
}

Example:

internal enum class MyEnum {
    MIDDLE_NAME
}
internal enum class MyEnumTwo {
    FIRST_NAME
}
internal enum class MyEnumThree {
    LAST_NAME
}


private fun demo(){

    System.out.println(getEnumValue<MyEnumTwo>("FIRST_NAME"))
    System.out.println(getEnumValue<MyEnum>("MIDDLE_NAME"))
    System.out.println(getEnumValue<MyEnumThree>("LAST_NAME"))

}

Output:

System.out: FIRST_NAME

System.out: MIDDLE_NAME

System.out: LAST_NAME

Old answer:

fun getEnumValue(enumClass:Class<>, value:String):Enum<> { return Enum.valueOf>>(enumClass as Class>>, value) }

pRaNaY
  • 24,642
  • 24
  • 96
  • 146
  • That's pretty much what the standard `enumValueOf<>()` function does, but that's not what I need. I've clarified the question. – Eugene Sep 26 '17 at 21:32
0

Kotlin has a built-in function for that:

enum class Fruits {
    APPLE,
    ORANGE,
    BANANA
}

Fruits.valueOf("APPLE")
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
0

reified really helpful here, we don't need class as parameter with it:

inline fun <reified E : Enum<E>> getEnumVariable(name: String): E {
    return enumValues<E>().firstOrNull { it.name == name }
        ?: error("No enum variable $name of type ${E::class.simpleName} found")
}

or

inline fun <reified E : Enum<E>> getEnumVariable(name: String): E {
    return enumValueOf<E>(name)
}
ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257