This is not possible. Reified type has to be known at the compile time. This is accomplished by inlining the body of the function into the call site, where T
is known.
Parameterized class doesn't know its T
, so T
can't be used as a reified type.
The solution is to capture an instance of Class<T>
or KClass<T>
when initializing Item
and keep it in a property:
class Item<T : Enum<T>>(
private val enumClass: KClass<T>
) : SomeLibraryClass<T>() {
override fun test(key: String): T {
return java.lang.Enum.valueOf(enumClass.java, key)
}
}
Even better, if we don't plan to extend Item
, then we can make the constructor internal and provide a reified factory function that captures KClass
/Class
:
class Item<T : Enum<T>> @PublishedApi internal constructor(
private val enumClass: KClass<T>
) : SomeLibraryClass<T>() {
companion object {
inline fun <reified T : Enum<T>> create() = Item(T::class)
}
override fun test(key: String): T {
return java.lang.Enum.valueOf(enumClass.java, key)
}
}
We use it like this:
val item = Item.create<Color>()
println(item.test("RED"))
java.lang.Enum.valueOf
is far from ideal, but AFAIK unfortunately Kotlin does not provide a multiplatform and smooth way to acquire enum values from KClass
. This feature was requested years ago: https://youtrack.jetbrains.com/issue/KT-14743 , but still wasn't implemented.