Covariance lets a generic type preserve the subtype relationship of its type argument. If Cat is an Animal, a covariant Herd<Cat> can be used where Herd<Animal> is expected. This is useful for read-only, producer-style APIs: callers can retrieve values without changing the collection. section 11.3.3 section 11.3.2
Making a herd usable by a broader function
An invariant Herd<T> rejects Herd<Cat> when feedAll expects Herd<Animal>, even though every cat is an animal. Declaring the parameter as out T changes that relationship: class Herd<out T : Animal> { /* ... */ } fun feedAll(animals: Herd<Animal>) { /* feed each animal */ } fun takeCareOfCats(cats: Herd<Cat>) { feedAll(cats) } The call is safe because Herd exposes animals as produced values rather than accepting replacements. section 11.3.3
interface Producer<out T> { #1
fun produce(): T
}
Use out on a type parameter when the interface produces T. A Producer<Cat> can then stand in for a Producer<Animal>. section 11.3.3
A covariant type parameter follows these rules:
- Write out before the type parameter, as in Producer<out T> or Herd<out T>. section 11.3.3
- Use T only in out positions: return values and other produced results, not function parameter types that consume T. section 11.3.3
- Prefer covariance for read-only abstractions such as Kotlin’s List; MutableList remains invariant because mutation would make covariance unsafe. section 11.3.2 section 11.3.3
- Avoid fixing an invariant mismatch with an explicit cast; changing the API variance is safer when the API truly only produces T. section 11.3.3
Covariance is a compile-time subtyping rule, not a conversion of contained values. It describes whether generic instances with different type arguments can be substituted. Kotlin supports declaration-site variance with out; it also distinguishes the opposite direction, contravariance, for parameters used only in input positions. section 11.4 section 11.3.3
For example, Kotlin’s read-only List is covariant, so List<String> is a subtype of List<Any>. This differs from invariant generic classes, where changing String to Any normally creates an unrelated generic type. section 11.3.2 section 11.4


