Type erasure is the JVM implementation of generics in which a generic instance’s type arguments are not retained at run time. A List<String> and a List<Int> can both be recognized as List, but their element types are unavailable. This keeps less type information in memory, but it limits runtime inspection. section 11.2 section 11.2.1
Figure 11.4 At run time, you don’t know whether list1 and list2 were declared as lists of strings or integers. Each of them is just List. This introduces additional constraints to working with type arguments.
The runtime representation retains the List base type but not whether its elements were declared as strings or integers. section 11.2.1
The practical rule is that an is check cannot test a generic argument such as is List<String>, because the required information has been erased. It can test the base class with a star projection: is List<*> means “a List with unknown type arguments.” Kotlin requires type arguments in ordinary generic type uses, so the star projection provides the runtime-safe way to ask whether a value is a list at all. section 11.2.1
Casts can be structurally valid but element-unsafe
A cast such as c as? List<Int> can verify that c is a List, but cannot verify that its elements are Int. Kotlin therefore reports an unchecked-cast warning. A list of strings may pass the cast and fail later when code uses an element as a number. By contrast, when a parameter is already Collection<Int>, a runtime check can distinguish List<Int> from Set<Int>: the element type is known from the declared parameter type, while the check only distinguishes base collection classes. section 11.2.1 section 11.2.1
Reified type parameters address selected runtime checks. An inline function can mark T as reified, allowing value is T because the compiler inserts the function body at each call site and generates code for the concrete type argument. For example, isA<String>("abc") is true, and filterIsInstance<String>() can select strings from a mixed list. Inline is used here to enable reification, not necessarily for lambda-performance benefits. section 11.2.2 section 11.2.2
Reification has practical constraints:
- Use it in inline functions when behavior genuinely needs the concrete type argument at runtime. section 11.2 section 11.2.2
- Keep such inline functions small; move work unrelated to reified parameters into non-inline functions to avoid excessive generated code. section 11.2.2
- Do not expect a function with reified type parameters to be callable from Java; it requires Kotlin’s call-site inlining. section 11.2.2
Type erasure aligns Kotlin generics with Java: type arguments normally exist only at compile time. Use star projections when arguments are unknown or irrelevant, treat generic casts as potentially unsafe, and use inline reified parameters when a Kotlin call needs a concrete runtime type check. section 11.4 section 11.4

