Getting Class of list with generic eg: List<Number>::class
Due to generic type erasure List
class has a single implementation for all its generic instantiations. You can only get a class corresponding to List<*>
type, and thus create only Builder<List<*>>
.
That builder instance is suitable for building a list of something. And again due to type erasure what that something is you can decide by yourself with the help of unchecked casts:
Builder(List::class.java) as Builder<List<Number>>
Builder(List::class.java as Class<List<Number>>)
Another approach is to create inline reified helper function:
inline fun <reified T : Any> Builder() = Builder(T::class.java)
and use it the following way:
Builder<List<Number>>()
The solution is to use reified generics in couple with super class tokens.
Please refer to this question for the method explained. Constructors in Kotlin don't support reified generics, but you can use TypeReference
described there to write a builder
factory function which will retain actual generic parameters at runtime:
inline <reified T: Any> fun builder(): Builder<T> {
val type = object : TypeReference<T>() {}.type
return Builder(type)
}
Then inside Builder
you can check if type
is ParameterizedType
, and if it is, type.actualTypeArguments
will contain the actual generic parameters.
For example, builder<List<Number>>()
will retain the information about Number
at runtime.
The limitation of this approach is that you cannot use non-reified generic as a reified type parameter because the type must be known at compile-time.