Marc Knaup
10/24/2017, 5:43 PMinline fun <reified T> test() { … }
test<List<String>>()
I can get List::class
at compile-time without reflection.
What if I could also get the generic argument String
without knowing what T
will be?
Something like this:
inline fun <reified T> test() {
println("Type is ${T::class.simpleName} with arguments: ${T::arguments}")
}
test<Any>()
// prints something like: "Type is Any with arguments: []"
test<List<String>>()
// prints something like: "Type is List with arguments: [String]"
test<Map<String,Any>>()
// prints something like: "Type is Map with arguments: [String, Any]"
So basically T::arguments
could return the arguments of generic parameters of T
as Array<KClass<*>>
.
OTOH that still doesn’t support nested generics like Map<String, Map<String, Any>>
.
…
So what about providing something like Guava’s TypeToken
for reified parameters?
inline fun <reified T> test() {
println("Type is ${T::classToken}") // is a KClassToken<T> - name is just an example
}
test<Map<String,Map<String,Any?>>()
// prints something like: "Type is Map<String, Map<String, Any?>>>"
Basically allows you to access all generic info at runtime as well as nullability, allowing reified
parameters to work around type erasure.
Related: https://github.com/google/guava/wiki/ReflectionExplained#typetoken