I am running some experiments on Kotlin's reflection.
I am trying to get a reflection object of a generic class with its argument.
In Java, that would be a ParameterizedType
.
The way to get such a thing using Java's reflection API is a bit convoluted: create an anonymous subclass of a generic class, then get its super-type first parameter.
Here's an example:
@Suppress("unused") @PublishedApi
internal abstract class TypeReference<T> {}
inline fun <reified T> jGeneric() =
((object : TypeReference<T>() {}).javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
When I println(jGeneric<List<String?>>())
, it prints java.util.List<? extends java.lang.String>
, which is logical considering that Kotlin's List
uses declaration-site out
variance and that Java types have no notion of nullability.
Now, I would like to achieve the same kind of result, but with the Kotlin reflection API (that would, of course, contain nullability information).
Of course, List<String>::class
cannot work since it yields a KClass
. and I am looking for a KType
.
However, when I try this:
inline fun <reified T> kGeneric() =
(object : TypeReference<T>() {})::class.supertypes[0].arguments[0].type
When I println(kGeneric<List<String?>>())
, it prints [ERROR : Unknown type parameter 0]
, which is quite... well, anticlimactic ;)
How can I get, in Kotlin, a KType
reflecting List<String>
?