I'm trying to understand the purpose of the reified
keyword, apparently it's allowing us to do reflection on generics.
However, when I leave it out it works just as fine. Anyone care to explain when this makes an actual difference?
I'm trying to understand the purpose of the reified
keyword, apparently it's allowing us to do reflection on generics.
However, when I leave it out it works just as fine. Anyone care to explain when this makes an actual difference?
TL;DR: What is
reified
good forIn the body of a generic function like
myGenericFun
, you can't access the typeT
because it's only available at compile time but erased at runtime. Therefore, if you want to use the generic type as a normal class in the function body you need to explicitly pass the class as a parameter as shown inmyGenericFun
.If you create an
inline
function with a reifiedT
though, the type ofT
can be accessed even at runtime and thus you do not need to pass theClass<T>
additionally. You can work withT
as if it was a normal class, e.g. you might want to check whether a variable is an instance ofT
, which you can easily do then:myVar is T
.Such an
inline
function withreified
typeT
looks as follows:How
reified
worksYou can only use
reified
in combination with aninline
function. Such a function makes the compiler copy the function's bytecode to every place where the function is being used (the function is being "inlined"). When you call an inline function with reified type, the compiler knows the actual type used as a type argument and modifies the generated bytecode to use the corresponding class directly. Therefore calls likemyVar is T
becomemyVar is String
(if the type argument wereString
) in the bytecode and at runtime.Example
Let's have a look at an example that shows how helpful
reified
can be. We want to create an extension function forString
calledtoKotlinObject
that tries to convert a JSON string to a plain Kotlin object with a type specified by the function's generic typeT
. We can usecom.fasterxml.jackson.module.kotlin
for this and the first approach is the following:a) First approach without reified type
The
readValue
method takes a type that it’s supposed to parse theJsonObject
to. If we try to get theClass
of the type parameterT
, the compiler complains: "Cannot use 'T' as reified type parameter. Use a class instead."b) Workaround with explicit
Class
parameterAs a workaround, the
Class
ofT
can be made a method parameter, which then used as an argument toreadValue
. This works and is a common pattern in generic Java code. It can be called as follows:c) The Kotlin way:
reified
Using an
inline
function withreified
type parameterT
makes it possible to implement the function differently:There’s no need to take the
Class
ofT
additionally,T
can be used as if it was an ordinary class. For the client the code looks like this:Important Note: Working with Java
An inlined function with
reified
type is not callable from Java code.