面试题答案
一键面试协方差实现
open class Animal
class Dog : Animal()
// 协方差,使用out关键字
fun <T : Animal> processAnimalsOut(animals: List<out T>) {
for (animal in animals) {
val animalVar: Animal = animal // 可以安全地将T类型元素赋值给Animal类型变量
println(animalVar.javaClass.simpleName)
}
}
原理:在processAnimalsOut
函数中,使用out
关键字声明泛型T
,表示T
是一个协变类型。这意味着List<out T>
可以接受T
及其子类类型的列表。由于T
是Animal
或其某个子类,所以可以安全地将列表中的元素赋值给Animal
类型变量。
反协方差实现
// 反协方差,使用in关键字
fun <T : Animal> addDogToAnimalsIn(animals: MutableList<in T>) {
val dog = Dog()
animals.add(dog) // 可以安全地向列表中添加Dog类型元素
}
原理:在addDogToAnimalsIn
函数中,使用in
关键字声明泛型T
,表示T
是一个反协变类型。这意味着MutableList<in T>
可以接受T
及其超类类型的可变列表。因为Dog
是Animal
的子类,所以可以安全地向列表中添加Dog
类型元素。