Fundamentals 7 min read

Avoid Kotlin’s Inline, crossinline, and reified Pitfalls: Best Practices

This article explains the performance benefits and debugging challenges of Kotlin's inline, crossinline, and reified keywords, provides concrete code examples, and offers practical guidelines on when and how to use each feature safely.

AndroidPub
AndroidPub
AndroidPub
Avoid Kotlin’s Inline, crossinline, and reified Pitfalls: Best Practices

Preface

Kotlin inline, crossinline and reified keywords are powerful but easy to misuse. They promise “zero‑cost abstraction” but can cause unexpected issues if not used correctly.

1. inline: performance vs debugging trade‑off

The inline keyword tells the compiler to copy the function body to the call site, eliminating the function call overhead and avoiding lambda object allocation.

Reduces performance overhead of function calls (especially for small functions).

Avoids object creation from lambda expressions, reducing memory allocation.

Looks good, but there are pitfalls!

The main problem is that stack traces become confusing because the inlined function’s frame disappears.

inline fun runSafe(block: () -> Unit) {
    try {
        block()
    } catch (e: Exception) {
        println(e.stackTraceToString())
    }
}
fun fail() {
    throw RuntimeException("出错啦!")
}
fun main() {
    runSafe { fail() }
}

Expected stack trace shows runSafe, but after inlining the frame is gone, producing a truncated stack trace that makes debugging difficult.

RuntimeException: 出错啦!
    at fail
    at main

Correct advice

Add detailed logging inside inline functions to compensate for lost stack information.

Avoid using inline functions for complex error‑handling logic.

2. crossinline: the rescue in coroutines

Kotlin lambdas can perform non‑local returns, which is illegal inside coroutine contexts. Marking the lambda parameter with crossinline prevents non‑local returns, making it safe for use in suspend contexts.

inline fun runInlineCross(scope: CoroutineScope, crossinline block: () -> Unit) {
    scope.launch {
        block() // now safe
    }
}

3. reified: defeating type erasure

Java/Kotlin generics suffer from type erasure, so generic type information is unavailable at runtime. Combining inline with reified preserves the type.

inline fun <reified T> foo() {
    println(T::class) // works at runtime
}

This is useful for generic utilities such as JSON parsing:

inline fun <reified T> Moshi.getAdapter(): JsonAdapter<T> =
    this.adapter(T::class.java)

Precautions

reified

must be used together with inline.

Do not mark large functions as inline just to use reified, as it can cause bytecode bloat.

Frequent changes to inline functions in libraries can affect binary compatibility.

4. Practical recommendations

When to use inline

Small higher‑order functions (e.g., helper utilities).

DSL builders to improve readability.

Performance‑critical code paths.

When to avoid inline

Complex error‑handling logic.

Large functions that would increase bytecode size.

Functions where a full stack trace is required.

Best practices for crossinline

Use when the lambda is passed to a coroutine.

Use to forbid non‑local returns.

Use when the lambda is forwarded to another context.

Best practices for reified

Generic utility classes (JSON parsing, database operations).

Type checks and casts.

Building type‑safe APIs.

5. Debugging inline code tips

Decompile the APK with JADX to see the actual inlined code.

Combine ProGuard/R8 mapping files to restore obfuscated stack traces.

Remember that inlined functions do not appear in call graphs during performance analysis.

Conclusion

The three Kotlin keywords are powerful but act like a double‑edged sword; used correctly they enable elegant and efficient code, while misuse can hide hard‑to‑track bugs. Apply the guidelines above to write more robust Kotlin code.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DebuggingKotlincrossinlineInlinereified
AndroidPub
Written by

AndroidPub

Senior Android Developer & Interviewer, regularly sharing original tech articles, learning resources, and practical interview guides. Welcome to follow and contribute!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.