

How Kotlin’s reified keyword simplifies working with generics
source link: https://medium.com/@s1m0nw1/how-kotlins-reified-keyword-simplifies-working-with-generics-50a4e0cb254c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.


How Kotlin’s reified keyword simplifies working with generics
How to access generic types in a Kotlin function body
The Kotlin programming language comes with a great set of features that make a programmer’s life easier. Compared to Java, Kotlin offers many syntactic improvements and gimmicks that make programming a big pleasure. The reified
keyword is one of them. This keyword is unknown in many other languages and therefore many people don’t directly understand its purpose. In this little article, I will be going through an example to demonstrate the keyword’s purpose and use.
What are we talking about, anyways?
Software needs abstraction in order to solve many different things at the same time. Many popular and powerful languages such as Java or C++ (even Golang, as I hear) have support for generic types. The following function is an example, written in Kotlin:
fun <T> myGenericFun(c: Class<T>)
In an ordinary generic function like myGenericFun
, it is not possible to access the type T
in the function body directly. The way we make it work is by passing an argument of type Class
using the generic type T
into the function. The reason why this is needed is that, like in Java, all generic types are unavailable at runtime. Generic types are being erased during compilation. For this reason, it is not quite simple to reference the generic type in the function body. For instance, in some cases, you will want to access the type of T
within the implementation of your function. To do so, we need to explicitly pass the class as a parameter as done in the given example. This approach is totally correct and can be found in pretty much all Java code bases. However, Kotlin tries to simplify working with generics, which is where the reified
keyword comes in.
The reified type
to the rescue
If we take the example function from above and want to make use of the reified type Kotlin offers, the first prerequisite to follow is making the function inline
. Inlined functions are resolved by the compiler and its code is being copied over to all call sites. If we now add the reified
keyword to the generic type T
our signature looks as follows:
inline fun <reified T> myGenericFun()
With such a function, we can now work with T
as if it was a normal Class
, e.g. you might want to check whether a variable is an instance of T
, which you can easily do like this: myVar is T
.
Under the hood
Remember that reified
types can only be used in combination with inline
functions. An inline
function makes the compiler copy the function's bytecode to every place the function is called from. 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 like myVar is T
become e.g. myVar is String
in the bytecode and can therefore work at runtime.
Reified in Action
Let’s have a look at an example to demonstrate what value reified
actually brings. The task is to create an extension function on String
that is supposed to convert a JSON string into a Kotlin type that gets specified by the function's generic type T
. We will use com.fasterxml.jackson.module.kotlin
for this and our first attempt looks as follows:
The first approach without reified type
fun <T> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
//does not compile!
return mapper.readValue(this, T::class.java)
}
The readValue
method used in the last statement takes a type as it’s last argument (here: T::class.java
). This argument is used to specify the type the parsing is supposed to spit out. If we now refer to the type parameter T
within the function body, the compiler complains with the following error message: "Cannot use 'T' as reified type parameter. Use a class instead.". This error basically tells us that the generic type T is not usable the way our function is set up. Let’s fix it in a first iteration.
Workaround with explicit Class parameter
fun <T: Any> String.toKotlinObject(c: KClass<T>): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, c.java)
}
To work around the issue, we pass the Class
of T
explicitly, which we can simply pass through to readValue
. This approach is super common in the Java world and works as intended. On the call side, our code looks like this:
// type definitiondata class MyJsonType(val name: String)
// variable definitionval jsonTypeAsString = """{"name":"example"}"""
// call to String::toKotlinObjectjsonTypeAsString.toKotlinObject(MyJsonType::class)
The Kotlin way using reified
Using an inline
function with reified
type parameter T
makes it possible to implement our function as follows:
inline fun <reified T: Any> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, T::class.java)
}
There’s no need to pass the Class
of T
additionally, T
can be used as if it was an ordinary class. For the client, the code reduces to the following:
json.toKotlinObject<MyJsonType>()
Interoperability with Java
Inline reified functions are not callable from Java code, whereas normal inline functions are. This might be one of the reasons why not all generic types that are used in inline
functions become reified
by default.
Conclusion
We have seen that the reified
keyword can solve a common issue of the JVM’s generic type erasure. Many situations need us to access the generic type within the function body which is cumbersome to achieve on the function and also the callee side. This article went through a simple example to demonstrate the power of a reified type simplifying both the function implementation and the caller code.
If you liked this article please clap below 👏🏼 and feel free to follow me for more awesome content 🙏🏼😌
Recommend
-
342
Simon Wirtz Blog - Kotlin Reified Types in Inline Functions - Read how Kotlin makes generic functions more readable by using reified generic types.
-
166
TheWizardAndTheWyrd/kotlin-reified-factory master
-
71
Many have argued that run time access to generic type information is very important. A very bitter debate about this ensued when we added generics to Java. The topic recurs whenever one designs a statically typed object o...
-
74
使用Kotlin Reified 让泛型更简单安全 Jul 28th, 2019 我们在编程中,出于复用和高效的目的,我们使用到了泛型。但是泛型在JVM底层采取了类型擦除的实现机制,Kotlin也是这样。然后这也带来了一些问题和对应的解...
-
10
Limit the Availability of Kotlin Extension Functions by using Generics and an Empty InterfaceSometimes you need to limit which objects may run a particular extension function. [image from Bravo TV]Extension functions are...
-
7
Twitter is building a tool for keyword alerts, in case you need more Twitter notifications Think Google Alerts, but for Twitter By...
-
14
How Kotlin’s “reified” Keyword Simplifies Working With GenericsHow to access generic types in a Kotlin function body
-
6
Rust Keyword Generics Progress Report User: Password: | |
-
4
Introduction About 9 months ago we announced the creation of the Keyword Generics Initiative; a group working under the lang team with t...
-
3
Writing Swift-friendly Kotlin Multiplatform APIs — Part VIII: GenericsLearn how to code libraries that your iOS teammates will not frown upon using them. In this chapter: generics
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK