Kotlin基础 – 协变和逆变

Kotlin 里面:

  • in 是指可以写但是不可以读,是消费者,逆变;
  • out 是只可以读不能写,是生产者,协变;

对应Java

  • out 协变 对应 ? extends 只能读取不能修改 生产者

  • in 逆变 对应 ? super 只能修改不能读取 消费者

out

out(协变),如果泛型类只将泛型类型作为函数的返回(输出),那么使用out,可以称之为生产类/接口,因为它主要是用来生产(produce)制定的泛型对象。

我的理解:

open class TV {
open fun turnOn() {}
}

class XiaoMiTV1: TV() {
override fun turnOn() {}
}
class Controller<T> {
}
fun main() {	
//这里编译器会报错,Type mismatch: inferred type is TV but XiaoMiTV1 was expected
val tv1: Controller<TV> = Controller<XiaoMiTV1>()
}

对于上面的方法,将Controller转成Controller是不行的

我们在 Controller<T>方法上加上out关键字

class Controller<out T> {}

这就是泛型的一致性

open class Tea

class GreenTea: Tea()

class RedTea: Tea()

class DrinkTea<T>

fun main() {
val d1: DrinkTea<out Tea> = DrinkTea<RedTea>()
val d2: DrinkTea<in GreenTea> = DrinkTea<Tea>()
}

在上面的例子中,如果需要将子类 转为父类对象,就使用out,泛型的一致性,如果需要将父类转为子类,就使用in,父子关系颠倒了

Java Kotlin 边界 场景
<? extend T> out(协变) 上边界 取值
<? super T> in(逆变) 下边界 存值
不变 存值/取值