Contravariance lets a consumer of broad values stand in for a consumer of narrower values. In Kotlin, mark a type parameter with `in` when it is used only as input: if `Cat` is a subtype of `Animal`, then `Consumer<Animal>` is a subtype of `Consumer<Cat>`. The generic subtype direction is reversed because a consumer able to accept any animal can safely accept a cat. section 11.3.4
interface Comparator<in T> {
fun compare(e1: T, e2: T): Int { /* ... */ } #1
}
`Comparator` is contravariant because it receives values of `T` through `compare` rather than producing them. section 11.3.4
Reusing a general comparator
A `Comparator<Fruit>` can sort both `List<Fruit>` and `List<Apple>`. It knows how to compare every `Fruit`, so it can also compare the narrower `Apple` values. Similarly, where `sortedWith` requires `Comparator<String>`, a `Comparator<Any>` is safe because it handles strings along with other values. section 11.3.4
Use contravariance to model input-oriented APIs:
- Declare `Consumer<in T>` only when `T` occurs in input positions; a mutable structure that both accepts and returns `T` cannot use that simple declaration. section 11.3.4
- Recognize function types as mixed variance: `(T) -> R` is contravariant in its argument and covariant in its result. A function accepting `Animal` can therefore serve where one accepting `Cat` is needed. section 11.3.4 section 11.4
- Treat `FieldValidator<in T>` as a consumer: its `validate(input: T)` method makes a validator for a broader input type usable for a narrower one. section 11.3.6
Star projection deliberately removes the type argument. For a contravariant `Consumer<in T>`, `Consumer<*>` behaves as `Consumer<in Nothing>`: because its accepted input type is unknown, methods that take `T` cannot be called. This protects a heterogeneous validator map, but retrieving a validator with an unchecked cast can still select the wrong validator and fail at runtime. Encapsulate registration and typed retrieval to keep that cast in one controlled place. section 11.3.6 section 11.3.6
Contravariance is the input-side counterpart to covariance. Covariant `Producer<out T>` preserves subtype direction, contravariant `Consumer<in T>` reverses it, and invariant types provide no subtype relationship across different type arguments. section 11.3.4 section 11.4

