Kotlin Reified Generics: Explained

Kotlin Reified Generics: Explained

Kotlin is a wonderful language full of many little goodies and surprises that make day-to-day development so much more pleasant. Most of its goodies are really just a very smart compiler that does for you much of what you would have done anyway, and reified generics are a great example of that.

Kotlin is a wonderful language full of many little goodies and surprises that make day-to-day development so much more pleasant. Most of its goodies are really just a very smart compiler that does for you much of what you would have done anyway, and reified generics are a great example of that.

If you're sitting there thinking "what the are reified generics, and when should I use them?", then this post is for you. The following is an answer I posted in the Kotlin Slack to that exact question, and figured it might help people out here as well.

In normal Java generics, the generic parameter is only known at compile time, and is erased from the runtime. Kotlin’s reified generics allow you to pretend that the generic is still there at runtime, by effectively swapping out the placeholder <T> with the known type when it is actually used.

For example:

class JavaClass {
    <T> List<T> getList() { ... }
}
// somewhere else
List<String> list = new JavaClass().getList<String>();

effectively compiles in Java to

class JavaClass {
    List getList() { ... }
}
// somewhere else
List list = new JavaClass().getList();

The assumption here is that if the type-checker is able to verify at compile-time that everywhere that T is used, it is safe, then at runtime all calls to that method are safe and that T is not really needed any longer. But there are times that it would be nice to know that T parameter at runtime, which is what reified generics allows for.

An example where you might want to have that T at runtime is getting a value from a map, where the map can hold any type, and your class needs to check the type of the object in the map.

class JavaClass {
    <T> T getItemFromMap(String key) { 
        Object item = _map.get(key); // this is OK
        if(item instanceof T) { // compilation error, T is not known here at runtime
            return (T) item
        }
        else {
            return null;
        }
    }
}

The solution is to pass a Class object matching the T parameter, which has methods to do that check for you:

class JavaClass {
    <T> T getItemFromMap(Class<T> itemClass, String key) { 
        Object item = _map.get(key); // this is OK
        if(itemClass.isAssignableFrom(item.getClass())) { // this works
            return (T) item
        }
        else {
            return null;
        }
    }
}

But now our method is ugly, and we have to pass 2 parameters to it to get it to work, when at compile-time all the information is readily available. Reified generics make it possible to get around this restriction. The JVM fundamentally does not have the ability to make this work at runtime, so reified generics use a trick at compile-time to make it seem like that: it just inlines the function call and replaces the generic parameter with the actual Class in that inlined code.

Going back to the map example, we can rewrite it using reified generics like this:

inline fun <reified T> getItemFromMap(String key) { 
    val item = _map.get(key)
    if(T::class.java.isAssignableFrom(item.getClass())) {
        return (T) item
    }
    else {
        return null;
    }
}
// somewhere else
val list: String = getItemFromMap("key")

effectively compiles to

val item = _map.get(key)
val list: String = if(String::class.java.isAssignableFrom(item.getClass())) {
    (String) item
}
else {
    null;
}

I hope this was helpful!


by: Casey Brooks



kotlin android

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Top Android Projects with Source Code

Android projects with source code - Work on real-time android projects. We’ll start project ideas from beginners level and later move to advance projects.

Kotlin Coroutines on Android - How to use Coroutines on Android

Coroutines are a Kotlin feature that convert async callbacks for long-running tasks, such as database or network access, into sequential code. This Kotlin Coroutines tutorial will show you how to use coroutines on Android, and how the new androidx-concurrent library makes it easy to use them to get things off the main thread. You'll also learn how the new library helps coroutines work with Architecture Components. This session also covers coroutine patterns, best practices, and even how to test coroutines!

Building Dark Mode Theme in Android

Hello World, today we are going to see how we can implement a dark theme or night mode in our android application. This tutorial is going to be very simple and easy to understand. The dark theme is attractive to users and it is comfortable for low light conditions.

Build A Simple Application For Android Using Kotlin And Android Studio

Build A Simple Application For Android Using Kotlin And Android Studio - We will create a simple calculator android application which would be able to perform simple arithmetic calculations like…

Top 130 Android Interview Questions - Crack Technical Interview Now!

Top Android Interview Questions & Answers from Beginner to Advanced level. Get ready to crack your next android interview with these android interview questions