Reified type parameters are type parameters that retain more characteristics of actual types than normal type parameters do.
For a gentle introduction to the topic, check out the guide, Getting Real with Reified Type Parameters.
inline fun <reified T> Any.isInstanceOf(): Boolean = this is T
Here we created an extension function to wrap the more common
is operator. Why is this example so magical? Because normally, compiling
this is T would result in an error since the type of
T is erased.
To invoke the function above, we can do something like this:
val isStringAString = "String".isInstanceOf<String>() val isIntAString = 1.isInstanceOf<String>()
You can specify multiple parameters as
inline fun <reified T, reified U> haveSameType(first: T, second: U) = first is U && second is T
You can specify that some type parameters are reified and others are not:
inline fun <reified T, U> listOfTypeOrNull(obj: U): List<T>? = if (obj is T) listOf(obj) else null
You can also technically create an extension property that uses a reified type parameter, but it requires that the type parameter is used as the receiver type:
inline val <reified T> T.clazz get() = T::class.java
I haven’t been able to come up with a good use case for this, because you’ve got an actual object (
this) that lets you do even more than you could do with a reified type parameter. For example, the same property could be implemented like this:
val <T : Any> T.clazz get() = this.javaClass
To specify a reified type parameter:
- The keyword
reifiedgoes before the name in the type parameter declaration.
- The function must be declared
This second requirement also restricts where the function can go. For example, a local function (that is, a function defined inside another function) can’t be inlined.
Some of the main benefits of reified type parameters are:
- You can do type checks with
- You can do casts without unchecked cast warnings
- You can assign class objects by appending
::class.javato the parameter name. e.g.,
val x = T::class.java
There are klunky workarounds that Java developers have adopted over the years to accomplish these things, involving things like reflection, or passing
Class<T> objects as arguments to functions. Because reified type parameters are a more concise solution - especially when types can be inferred - they’re preferrable in most cases.
Since functions with reified type parameters must be declared
inline, one disadvantage is that you’d want to keep your function small, or else your compiled code will get bloated quickly. On the other hand, writing small, focused functions is usually considered a good practice anyway.