Inline functions in Kotlin are defined using the keyword inline and instruct the compiler to "insert" the body of the function directly at the call sites. This reduces the overhead of function calls, especially when using lambdas or short functions, and eliminates the allocation of additional objects for capturing closures.
Example:
inline fun synchronized(lock: Any, block: () -> Unit) { kotlin.synchronized(lock) { block() } }
Main advantages:
Disadvantages:
Recommendation: Use inline when you need to improve performance in critical parts of code where lambdas are widely used.
What limitation exists for inline functions when working with reified argument types?
The common wrong answer: "Reified types are always available within any inline function."
The correct answer: Only inline functions can use the reified modifier in the generic declaration, allowing access to the type at runtime:
inline fun <reified T> getTypeName() = T::class.java.name
In a regular generic function, accessing the type T during execution will not be possible.
Story
Poorly used inline led to bloated APK: In an Android project team, programmers marked dozens of utility functions as inline, including functions with large complex bodies. The result — the size of the APK increased by almost 2 MB due to the duplication of functions at all call sites.
Story
Error with lambdas and access to private variables: An inline function was used with a lambda that accessed private members of a class. After moving the function to an external module, the code stopped compiling (privileges were violated), which was only discovered in CI.
Story
Using reified outside of an inline function: One of the developers attempted to declare a function with a reified generic parameter without the inline modifier. The code did not compile, leading to a lengthy investigation by a newcomer as to why "T::class" was not available outside of inline functions.