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