Inline Functions & reified
An inline function is copied directly into each call site by the compiler, eliminating the object allocation a passed lambda would otherwise need and enabling reified type parameters that survive at runtime.
Learn Inline Functions & reified in our free Kotlin course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Kotlin course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
You'll learn why higher-order functions benefit from inline , how reified lets you check a generic type at runtime, and what noinline and crossinline are for.
What You'll Learn in This Lesson
1️⃣ What inline Does (and Why It Helps)
Marking a function inline asks the compiler to paste its body — and the body of any lambda you pass to it — directly where the function is called, instead of generating a real call. The program behaves identically; only the compiled bytecode changes. The payoff appears with higher-order functions: a passed lambda would normally become a heap-allocated object, and inlining removes that object entirely.
For a one-off call the difference is invisible, but inside a loop that runs millions of times, removing the per-call lambda allocation is exactly why Kotlin's map , filter , and forEach are all declared inline .
2️⃣ reified: Knowing T at Runtime
On the JVM, generic types are normally erased — at runtime a generic function has no idea what T was, so item is T won't compile. Because an inline function is copied into each call site, the compiler can substitute the real type there. Marking the type parameter reified unlocks exactly that, letting you write is T and T::class .
reified is only allowed on inline functions, because the type substitution happens precisely during the copy-into-call-site step.
3️⃣ A Real reified Helper (and noinline / crossinline)
The standard library's filterIsInstance<T>() is built from these ideas. Here we write our own. Two modifiers refine inlining: noinline on a lambda parameter keeps that one lambda as a real object (so you can store or forward it), and crossinline forbids non-local returns when a lambda is invoked from another context.
You rarely need noinline or crossinline day to day — plain inline plus reified covers the vast majority of real code.
Your turn. Fill in the ___ , then run and compare.
Write a reified function that counts how many list items match a given type.
📋 Quick Reference — inline & reified
Practice quiz
What does marking a function 'inline' do?
- Runs it on a separate thread
- Copies its body into each call site
- Makes it asynchronous
- Caches its return value
Answer: Copies its body into each call site. inline copies the function body — and passed lambdas — directly into the call site.
Which functions benefit most from inlining?
- Functions with no parameters
- Recursive functions
- Higher-order functions that take lambdas
- Functions returning Unit
Answer: Higher-order functions that take lambdas. Inlining removes the per-call lambda object, so higher-order functions benefit most.
What problem does inlining a lambda parameter avoid?
- Heap allocation of a lambda object
- Stack overflow
- Type erasure of return types
- Null pointer exceptions
Answer: Heap allocation of a lambda object. Normally each passed lambda becomes a heap object; inlining removes that allocation.
A 'reified' type parameter is only allowed on which kind of function?
- Suspend functions
- Abstract functions
- Extension functions
- inline functions
Answer: inline functions. reified requires inline, because the type is substituted as the body is inlined.
What does reified let you write that a plain generic cannot?
- item is T and T::class
- a return statement
- a default argument
- a nullable type
Answer: item is T and T::class. With reified, T survives at runtime so you can write is T and T::class.
Why is 'item is T' normally illegal in a generic function?
- T must be a class
- Generic types are erased at runtime on the JVM
- is only works on numbers
- T is always null
Answer: Generic types are erased at runtime on the JVM. JVM type erasure removes T at runtime, so is T won't compile without reified.
What does 'noinline' on a lambda parameter do?
- Forbids returning from the lambda
- Makes the whole function inline
- Keeps that one lambda as a real object so it can be stored or passed on
- Deletes the lambda
Answer: Keeps that one lambda as a real object so it can be stored or passed on. noinline keeps that lambda as a real object so you can store or forward it.
What does 'crossinline' enforce?
- It forbids non-local returns from the lambda
- It forces inlining of all callers
- It makes the lambda nullable
- It reifies the type parameter
Answer: It forbids non-local returns from the lambda. crossinline forbids non-local returns when the lambda is invoked from another context.
Which standard library function is built on reified type filtering?
- mapNotNull
- filterIsInstance
- groupBy
- associateWith
Answer: filterIsInstance. filterIsInstance<T>() uses an inline reified type parameter to filter by type.
What is a downside of marking a large function inline?
- It becomes thread-unsafe
- It can bloat the generated bytecode
- It cannot return a value
- It loses type safety
Answer: It can bloat the generated bytecode. Inlining copies code, so inlining big bodies bloats bytecode for little benefit.