Reified in Kotlin: Generics Magic for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

What is reified in Kotlin and why is it "magic"?

\n

If you've ever written in Java, you've certainly encountered Type Erasure — the erasure of types at runtime. In Java (and in Kotlin by default), type information inside generics is only available at compile time, and disappears at runtime. This means you cannot write if (value is T) or T::class inside a regular function, because T at runtime is just Object.

\n

But Kotlin went further. The keyword reified allows you to "revive" the type inside an inline function. Thanks to reified, you can do what seemed impossible in Java: check the type, get KClass, create instances, and even work with reflection — all at runtime.

\n

In this article, we'll break down how reified works with real examples you can apply immediately. Let's go!

\n\n

The Problem: Type Erasure in Action

\n

Imagine: you're writing a function that should check if an object is a string. A naive attempt:

\n
fun <T> isString(value: Any): Boolean {\n    return value is T // Compilation error!\n}
\n

The compiler will give an error: "Cannot check for instance of erased type: T". Why? Because at runtime, the JVM doesn't know what T is. For it, T is just Object.

\n

The same goes for getting the class: T::class inside a regular function won't work either. This is Type Erasure — the main headache for Java developers.

\n\n

The Solution: reified + inline

\n

Kotlin offers an elegant way out. To "remember" the type at runtime, you need to make the function inline and mark the type parameter with the keyword reified:

\n
inline fun <reified T> isString(value: Any): Boolean {\n    return value is T // Now it works!\n}
\n

Now you can call:

\n
println(isString<String>("Hello")) // true\nprintln(isString<Int>("Hello"))    // false
\n

How does it work? When you mark a function as inline, the compiler inlines its code directly at the call site. And reified forces the compiler to substitute the specific type (e.g., String) instead of T in the generated code. As a result, an explicit check value is String appears in the bytecode.

\n\n

Practical Examples of Using reified

\n

Let's look at several real-world scenarios where reified really simplifies life.

\n\n

1. Getting the Class at Runtime

\n

One of the most common tasks is to get KClass or Class from a type parameter. Without reified, this is impossible:

\n
inline fun <reified T> getKClass(): KClass<T> = T::class\n\n// Usage:\nval kClass = getKClass<String>()\nprintln(kClass.simpleName) // String
\n

This is especially useful when working with libraries that require reflection (e.g., serialization, ORM, DI containers).

\n\n

2. Creating an Instance by Type

\n

Want to create an object of the required type without passing a constructor? Easy:

\n
inline fun <reified T : Any> createInstance(): T {\n    return T::class.createInstance()\n}\n\n// Example:\nval instance = createInstance<StringBuilder>()\ninstance.append("Hello, reified!")
\n

But be careful: createInstance() only works if the class has a no-argument constructor. Otherwise, you'll get an exception.

\n\n

3. Filtering by Type in Collections

\n

Suppose you have a list of objects of different types, and you want to filter only strings. The Kotlin standard library has filterIsInstance<T>(), but you can easily write your own version:

\n


                
                

Blogs

Book Recommendations