Type Erasure and reified Type Parameters
Use reified with inline functions to access type information at runtime.
Type Erasure and reified Type Parameters is a free Kotlin Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Kotlin Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is Type Erasure?
At runtime, JVM erases generic type arguments. List<String> and List<Int> are both just List. This limits runtime type operations on generics.
fun main() {
val strings: List<String> = listOf("a", "b")
val ints: List<Int> = listOf(1, 2)
println(strings.javaClass == ints.javaClass) // true: both ArrayList
println(strings is List<*>) // OK with star
// println(strings is List<String>) // warning: unchecked cast
}The Problem: Cannot Check Erased Types
You cannot use is with a specific generic type argument because the type info is gone at runtime.
fun checkType(obj: Any) {
// This works:
if (obj is List<*>) println("It's a list of something")
// This doesn't compile cleanly:
// if (obj is List<String>) println("It's a list of strings") // unchecked
}
fun main() {
checkType(listOf("hello"))
checkType(42)
}inline Functions Recap
inline copies the function body to the call site at compile time. This is what enables reified — the type argument is also substituted at the call site.
inline fun <T> myRun(block: () -> T): T = block()
fun main() {
val result = myRun { 42 }
println(result) // 42
// The compiler inlines the lambda body — no object allocation
}reified: Accessing T at Runtime
Combining inline with reified preserves the type argument at the call site, enabling is, as, and ::class on T.
inline fun <reified T> isInstance(value: Any): Boolean = value is T
fun main() {
println(isInstance<String>("hello")) // true
println(isInstance<Int>("hello")) // false
println(isInstance<List<*>>(listOf())) // true
}Getting the KClass of T
With reified T, you can get T::class at runtime — normally impossible in generic functions.
inline fun <reified T> classNameOf(): String = T::class.simpleName ?: "Unknown"
fun main() {
println(classNameOf<String>()) // String
println(classNameOf<Int>()) // Int
println(classNameOf<List<*>>()) // List
}Safe Cast with reified
Use reified to write a type-safe cast utility that returns null instead of throwing.
inline fun <reified T> Any?.safeCast(): T? = this as? T
fun main() {
val obj: Any = "Hello"
val s: String? = obj.safeCast<String>()
val i: Int? = obj.safeCast<Int>()
println(s) // Hello
println(i) // null
}JSON Parsing with reified
Libraries like Gson or kotlinx.serialization use reified to infer the target type at the call site without passing Class objects explicitly.
import com.google.gson.Gson
// Simulated without real Gson:
inline fun <reified T> parseJson(json: String): T {
return Gson().fromJson(json, T::class.java)
}
// Usage:
// val user: User = parseJson<User>("""{"name":"Alice"}""")reified with filterIsInstance
The standard library's filterIsInstance<T>() uses reified to filter a list to a specific type without manual casting.
fun main() {
val mixed: List<Any> = listOf(1, "hello", 2.5, "world", true)
val strings = mixed.filterIsInstance<String>()
val ints = mixed.filterIsInstance<Int>()
println(strings) // [hello, world]
println(ints) // [1]
}Cannot Use reified in Non-inline Functions
reified only works with inline functions. Trying to use it without inline is a compile error.
// Error:
// fun <reified T> broken(): String = T::class.simpleName ?: "?"
// Must be inline:
inline fun <reified T> correct(): String = T::class.simpleName ?: "?"
fun main() {
println(correct<Double>()) // Double
}reified and Reflection
Combine reified with reflection to inspect properties or annotations of a type dynamically without boilerplate Class parameters.
inline fun <reified T : Any> properties(): List<String> =
T::class.members.map { it.name }
data class Point(val x: Int, val y: Int)
fun main() {
println(properties<Point>()) // [x, y, component1, component2, copy, equals, hashCode, toString]
}Practical: Type-Safe Service Locator
Use reified to build a service locator that maps KClass to instances for lightweight DI without annotation processors.
val registry = mutableMapOf<kotlin.reflect.KClass<*>, Any>()
inline fun <reified T : Any> register(instance: T) { registry[T::class] = instance }
@Suppress("UNCHECKED_CAST")
inline fun <reified T : Any> resolve(): T = registry[T::class] as T
class Logger { fun log(msg: String) = println("[LOG] $msg") }
fun main() {
register(Logger())
resolve<Logger>().log("Service located!")
}Limitations of reified
reified type parameters cannot be used in non-inline contexts, cannot store the type for later use, and cannot be passed to non-inline functions that need the type at runtime.
inline fun <reified T> foo() {
val clazz = T::class // OK here
// bar(clazz) // must pass clazz explicitly to non-inline funs
println(clazz.simpleName)
}
fun bar(clazz: kotlin.reflect.KClass<*>) = println(clazz.simpleName)
fun main() { foo<String>() }Quick Check
What is required for a type parameter to be reified?
Recap
Type erasure removes generic type info at runtime. reified on inline functions preserves the type argument at the call site, enabling is, as, ::class, and reflection on T — without passing Class objects manually.
Frequently asked questions
Is the “Type Erasure and reified Type Parameters” lesson free?
Yes — the full text of “Type Erasure and reified Type Parameters” is free to read here on the web, and the Kotlin Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Kotlin Academy course, upgrade to CoddyKit PRO.
What will I learn in “Type Erasure and reified Type Parameters”?
Use reified with inline functions to access type information at runtime. You practise Kotlin Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Kotlin Academy?
No prior experience is required. Kotlin Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Type Erasure and reified Type Parameters” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Kotlin Academy lesson?
Yes. Every Kotlin Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Generic Functions and Type Constraints with where
- Declaration-Site Variance: in and out
- Star Projection and When to Use *
- Type Erasure and reified Type Parameters