We break down how subtyping works for generic types in Kotlin: why
List<Expense> can be safely used as
List<Transaction>, but
MutableList<Expense> cannot be lifted to
MutableList<Transaction>. With examples, we show invariance of containers (
Box<T>), covariance of read-only collections, compiler errors, and practical API design techniques (accept
List if you don’t need to mutate), plus intuition via function types
(Transaction) -> String.