
型变(variance)是 Kotlin 泛型里最容易"用过但说不清"的一题。它的核心只有一条规则——型变位置约束:out类型只出现在返回位,in类型只出现在参数位——但从这一条能推导出协变/逆变哪些签名合法、哪些非法,以及为什么Listout T不能接受add。答得全的人,都是从这条规则推出来的。先把结论放在前面:Kotlin 用声明处型变(Java 用使用处型变,即通配符? extends/? super)。out T表示协变——ListSub是ListSuper的子类型,T 只出现在返回位置;in T表示逆变——ConsumerSuper可以传给ConsumerSub,T 只出现在参数位置。in+out同时标注(in out T)在 Kotlin 里是声明不变但两次投影的变体,含义是"写时投影、读时投影",用在既读又写的场景(比如MutableListin out T实际等价于Mutabl