ProgrammingAndroid Developer

Explain the difference between regular, inline, and reified generic parameters in Kotlin. When and why is reified used, what limitations of the standard generic approach does it lift?

Pass interviews with Hintsage AI assistant

Answer

In Kotlin, generics (generic parameters) are erased by default (type erasure): there is no type information at runtime. This complicates reflection, type casting, and reading type annotations. For most tasks, this is acceptable — regular generics work similarly to Java.

Inline functions with the reified parameter allow the compiler to "substitute" a specific type at the call site, enabling the function to perform operations with types at runtime (for example, performing checks, creating new instances using reflection, etc.). However, reified can only be applied to parameters in inline functions.

Comparison example:

// Regular generic fun <T> printType(t: T) { println(t.javaClass) // Will throw ClassCastException for List<Int> and others. } // with reified inline fun <reified T> printType(t: T) { println(T::class.simpleName) } fun main() { printType(123) // Outputs: Int printType("hello") // Outputs: String }

Practical application: Most often used for type checking, casting, reflection, instantiation, where it is impossible to get the type otherwise.

Trick question

"Can a function with a reified type be non-inline?"

  • No — reified works only in inline functions. Otherwise, type substitution at compile time is impossible.

Example of incorrect usage:

fun <reified T> failFunction() {} // Compilation error: reified type parameter can only be used on an inline function

Correct:

inline fun <reified T> goodFunction() {}

Examples of real errors due to ignorance of the subtleties of the topic


Story

The project required universal parsing of JSON strings into any type through a function with a generic parameter. The standard implementation via fun <T> parse(json: String): T did not work correctly due to type erasure — it was impossible to retrieve Class<T> for parsing collections and generic models. The issue was resolved through inline with a reified type — the problem disappeared.


Story

One of the developers was trying to create instances of type T using a regular constructor T(), not using inline and reified. A compilation error occurred because type information was erased. Refactoring to inline fun <reified T: Any> resolved everything using standard language tools.


Story

When trying to use reified in a regular function (without inline) — the IDE gave a confusing compilation error. The developer spent a long time searching for the cause until they studied the documentation and fixed the function by adding inline.