When to Use Kotlin Reified Type Parameters: A Practical Guide
Kotlin’s reified type parameters let you access generic type arguments at runtime inside inline functions, eliminating reflection. This guide shows how, why, and when to use them, with a concrete factory example, bytecode verification steps, and trade‑offs to watch for.
17 Mar 2026, 02:48 UTC

Problem
When writing generic APIs in Kotlin, you often need the actual type at runtime to perform operations like JSON deserialization or type‑safe casting. Java’s type erasure forces you to pass a Class<T> or use reflection, which is verbose and incurs runtime overhead.
Thesis
Kotlin’s reified type parameters on inline functions give you compile‑time knowledge of the concrete type, letting you write cleaner, faster code without reflection.
1. What Are Reified Type Parameters?
Normally, generic parameters are erased at runtime. By marking a type parameter as reified in an inline function, the compiler substitutes the concrete type at every call site. The resulting bytecode contains the concrete class reference, so the function can safely cast, check is, or instantiate objects.
Key Points
- Only works on
inlinefunctions. - Cannot be used when the function is passed as a value (e.g., to another higher‑order function).
- Eliminates the need for
Class<T>parameters orTypeTokenpatterns.
2. Practical Use Case – Generic Factory
Suppose you need a factory that creates instances of different data classes from JSON. A naive approach requires a Class<T> argument:
inline fun <T> createFromJson(json: String, clazz: Class<T>): T {
return Gson().fromJson(json, clazz)
}
With a reified type, you can drop the Class parameter and call the function directly with the target type:
inline fun <reified T> createFromJson(json: String): T? {
return Gson().fromJson(json, T::class.java)
}
// Usage
val user: User? = createFromJson<User>(jsonString)
The compiler inlines T::class.java, so no reflection is performed at runtime.
3. Trade‑Offs & Limitations
- Bytecode bloat: Each call site generates a new bytecode version of the function, increasing class file size and DEX size on Android.
- Compilation time: More bytecode can slow down the build, especially in large projects with many call sites.
- Higher‑order functions: You cannot pass a reified inline function as a lambda because the compiler cannot inline it at the call site.
- Android impact: Larger DEX files may affect app startup time.
4. How to Verify the Effectiveness
- Compile the code:
kotlinc MyFactory.kt -include-runtime -d myfactory.jar - Inspect the bytecode to confirm no reflection and that the concrete type is inlined:
You should seejavap -c -classpath myfactory.jar com.example.MyFactoryT::class.javareplaced with the actual class literal, e.g.,com.example.User.class. - Benchmark (optional): Measure a reified cast versus a cast using
Class<T>and reflection to observe the performance difference.
Conclusion
Reified type parameters are a powerful tool when you need type information at runtime without the verbosity and overhead of reflection. Use them for concise generic factories, DSL builders, or any scenario where the type is known at the call site. Keep an eye on bytecode size and compilation times, especially in Android projects, and avoid passing reified functions as lambda arguments.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.