A type argument supplies a concrete type wherever a generic class, interface, or function has a type parameter. `List<String>` says a list holds strings; `Map<String, Person>` supplies separate arguments for keys and values. Kotlin requires every generic type argument to be explicit or inferred, unlike Java raw types such as `ArrayList` without an element type. section 11.1
Specify an argument only when inference needs help
The compiler infers `String` from the values passed to `listOf`, so the result is `List<String>`. An empty collection has no values to reveal its element type, so provide it either on the variable or the factory function. `val authors = listOf("Sveta", "Seb")` `val readers: MutableList<String> = mutableListOf()` `val readers = mutableListOf<String>()` section 11.1
Generic functions receive type arguments at each call. Usually Kotlin infers them from the receiver and arguments, then substitutes the result type accordingly. Calling `slice` on a `List<Char>` produces `List<Char>`; explicit syntax such as `slice<Char>(0..2)` remains available when it improves clarity or inference cannot determine the type. section 11.1.1
Listing 11.1 Calling a generic function
fun main() {
val letters = ('a'..'z').toList()
println(letters.slice<Char>(0..2)) #1
// [a, b, c]
println(letters.slice(10..13)) #2
// [k, l, m, n]
}
Compare an explicit function type argument with the inferred form; both calls return a list of characters. section 11.1.1
Type arguments also determine what a generic declaration can safely express:
- A generic class uses its parameter in member types: `List<T>` can return `T`, while `StringList : List<String>` returns `String`. section 11.1.2
- Upper bounds restrict eligible arguments. `<T : Number>` accepts numeric subtypes, and `<T : Comparable<T>>` requires values comparable with their own type. section 11.1.3
- An unconstrained parameter accepts nullable arguments because its effective upper bound is `Any?`; `<T : Any>` excludes nullable types. section 11.1.4
- Nested and nullable arguments form distinct types, such as `List<Int>`, `List<String?>`, and `List<List<String>>`. section 11.3.2
On the JVM, ordinary type arguments are checked by the compiler but erased at run time. A `List<String>` and `List<Int>` are both only a `List` at execution, so `is List<String>` is not allowed. The compiler still preserves static safety unless casts or Java raw types bypass it. section 11.2.1
Reify a function argument for a runtime check
An inline function can mark its parameter `reified`, making the actual argument available in its inlined body. This enables `is T` checks and supports utilities such as `filterIsInstance<String>()`, which selects strings from a mixed collection and returns `List<String>`. `inline fun <reified T> isA(value: Any) = value is T` section 11.2.2
Type arguments also affect subtype relationships. Kotlin permits `List<String>` where `List<Any>` is expected because read-only `List` is covariant, but rejects `MutableList<String>` as `MutableList<Any>` because a consumer could add a non-string. Use-site `out` and `in` projections express corresponding producer and consumer constraints, paralleling Java bounded wildcards. section 11.3.1 section 11.3.5
When the exact argument is unknown or irrelevant, a star projection can stand in for it. For example, an annotation parameter can use `KClass<out ValueSerializer<*>>` to require a serializer class without committing to the property type it handles. section 12.1.7




