Why must a function be marked `inline` for its type parameter to be `reified`? What does the compiler do?
answer
- inline = body copied to call site
- call site knows the real type
- reified only allowed with inline
- erasure removes T at runtime
- is T / T::class become legal
basics
~20 sBecause inline copies the function's body into each call site. There the compiler already knows the real type you used, so it can replace the type parameter with that concrete class. A normal function has no copy and no known type.
solid answer
~40 sOn the JVM, generic type arguments are erased at runtime — a normal generic function never knows its concrete `T`. The `reified` modifier works only with `inline` functions because the compiler copies (inlines) the function body directly into every call site. At each call site the actual type argument is statically known, so the compiler substitutes `T` with that concrete class everywhere in the inlined body. That makes expressions like `T::class`, `is T`, and `T::class.java` legal. Without `inline` there is no call-site copy to substitute into, so the compiler reports an error: `Type parameter T cannot be reified because the function is not inline`. The cost is that the body is duplicated at each call site, so reified functions should stay small.
code
kotlin · 6 linesinline fun <reified T> Any.isA(): Boolean = this is T
fun main() {
println("x".isA<String>()) // true -> inlined as: "x" is String
println(42.isA<String>()) // false -> inlined as: 42 is String
}go deeper
States that inline copies the body into the call site and that the concrete type is known there, so T can be substituted.
Connects it to JVM erasure and names the exact unlocked operations (T::class, is T, as? T) and the compiler error.
Explains the substitution happens per call site, the code-size trade-off, and when to avoid reified on large/hot functions.
Frames reified as a compile-time monomorphization shim over an erased runtime, and reasons about API design vs. bytecode bloat across a library surface.
## The problem: type erasure On the JVM, generics use **type erasure**: at runtime `List<String>` and `List<Int>` are both just `List`, and a generic function's type parameter `T` carries no `Class` token. So inside an ordinary `fun <T> foo()` you cannot write `T::class`, `x is T`, or `T::class.java` — the compiler rejects them because the information is gone at runtime. ## How `inline` changes the picture The `inline` keyword tells the compiler to **copy the function body into each call site** instead of generating a real call. After inlining, the code lives where the function was *invoked*, and at an invocation the concrete type argument is **statically known**. ```kotlin inline fun <reified T> isInstance(value: Any): Boolean = value is T val ok = isInstance<String>("hi") // after inlining the compiler effectively produces: // val ok = "hi" is String ``` Because the body is pasted in with `T` replaced by the concrete `String`, the otherwise-illegal `value is T` becomes the perfectly legal `value is String`. ## What `reified` actually does `reified` is a modifier on a **type parameter** (`<reified T>`) that is only allowed when the function is `inline`. It instructs the compiler to substitute `T` with the real class at every call site. This unlocks: - `T::class` and `T::class.java` (KClass / Class tokens) - `value is T` and `value as? T` (runtime type checks/casts) - passing `T` to another reified function ## Why non-inline can't do it A non-inline function compiles to **one** shared method body. There is no per-call-site copy to substitute a concrete type into, and at runtime `T` is erased — so the compiler errors: *"Type parameter T cannot be reified because the function 'foo' is not inline."* Marking the function `inline` is the fix. ## The canonical use This is what powers ergonomic APIs such as `inline fun <reified T> Gson.fromJson(json: String): T`, letting you write `gson.fromJson<User>(json)` instead of passing `User::class.java` explicitly. ## Trade-off Inlining duplicates bytecode at every call site, so keep reified functions small and avoid them on hot mega-functions where code-size matters.
- What exact compiler error appears if you write `reified` without `inline`?"Type parameter T cannot be reified because the function 'foo' is not inline" — the fix is to add the `inline` modifier.
- Does `inline` alone make `T` reified?No. `inline` enables it, but you must also explicitly mark the type parameter `reified`. A plain inline generic still has an erased `T`.
It's like a mail-merge: the template (function) is copied into each letter (call site) with the real name (concrete type) filled in, so by the time it runs there's nothing generic left.
saying these in an interview costs you the question
- Claiming reified works on any generic function regardless of inline
- Saying inline is about performance only and ignoring the substitution mechanism
- Thinking the JVM keeps the type at runtime for reified params (it's a compile-time substitution)
- Confusing reified with passing a Class<T> parameter