Goal: support run-time access to types passed to functions, as if they were reified (currently limited to inline functions only).
A type parameter of a function can be marked as reified
:
inline fun foo<reified T>() {}
Definition A well-formed type is called runtime-available if
C
, where C
is a classifier (object, class or trait) that has either no type parameters, or all its type parameters are reified
, with the exception for class Nothing
,G<A1, ..., An>
, where G
is a classifier with n
type parameters, and for every type parameter Ti
at least one of the following conditions hold:Ti
is a reified
type parameter and the corresponding type argument Ai
is a runtime-available type,Ai
is a star-projection (e.g. for List<*>
, A1
is a star-projection);T
, and T
is a reified
type parameter.Examples:
String
, Array<String>
, List<*>
;Nothing
, List<String>
, List<T>
(for any T
)T
is runtime-available iff the type parameter T
is reified
, same for Array<T>
Only runtime-available types are allowed as
is
, !is
, as
, as?
reified
type parameters of calls (for types any arguments are allowed, i.e. Array<List<String>>
is still a valid type).As a consequence, if T
is a reified
type parameter, the following constructs are allowed:
x is T
, x !is T
x as T
, x as? T
T
: javaClass<T>()
, T::class
(when supported)Restrictions regarding reified type parameters:
inline
function can be marked reified
Array
is the only class whose type parameter is marked reified
. Other classes are not allowed to declare reified
type parameters.reified
type parameterNotes:
inline
functions declaring no inlinable parameters of function types, but having a reified
type parameter declared.In inline functions, occurrences of a reified
type parameter T
are replaced with the actual type argument. If actual type argument is a primitive type, it's wrapper will be used within reified bytecode.
open class TypeLiteral<T> { val type: Type get() = (javaClass.getGenericSuperclass() as ParameterizedType).getActualTypeArguments()[0] } inline fun <reified T> typeLiteral(): TypeLiteral<T> = object : TypeLiteral<T>() {} // here T is replaced with the actual type typeLiteral<String>().type // returns 'class java.lang.String' typeLiteral<Int>().type // returns 'class java.lang.Integer' typeLiteral<Array<String>>().type // returns '[Ljava.lang.String;' typeLiteral<List<*>>().type // returns 'java.util.List<?>'