从Java说起 kotlin 的协变与逆变

原创
ithorizon 8个月前 (09-09) 阅读数 85 #Java

从Java说起:Kotlin的协变与逆变

在Java编程语言中,泛型的引入为类型保险提供了强势的保障,但它也有自己的局限性。其中一个局限就是类型通配符的纷乱性,特别是在涉及类型边界时。Kotlin作为Java的姊妹语言,在Java泛型在出现的同时进行了改进,引入了协变(covariance)与逆变(contravariance)的概念,让泛型的使用更为灵活和便捷。

Java中的泛型局限性

在Java中,泛型类型参数是不变的(invariant),这意味着List并不被认为是List的一种。以下是一个易懂的示例:

// Java代码

List apples = new ArrayList<>();

List fruits = apples; // 编译不正确,类型不匹配

以上代码无法通过编译,由于Java的泛型不拥护下界类型转换。为了解决这个问题,Java引入了通配符?

Kotlin的协变

Kotlin通过out关键字提供了协变拥护,允许将一个泛型类型的子类对象赋值给父类的泛型对象。

// Kotlin代码

open class Fruit

class Apple : Fruit()

fun main() {

val apples: List = listOf()

val fruits: List = apples // 这是允许的,由于List是协变的

}

在Kotlin中,List描述这个列表只能生产(produce)Apple或者其子类型的对象,但不能接受Apple的父类型对象。这里的out关键字描述了泛型类型的输出位置,即生产者(Producer)。

Kotlin的逆变

Kotlin同样提供了逆变的拥护,通过使用关键字in。逆变允许将一个泛型类型的父类对象赋值给子类的泛型对象。

// Kotlin代码

fun main() {

val fruits: List = listOf()

val apples: List = fruits // 这是允许的,由于List是逆变的

}

在这里,List描述这个列表可以接受(consume)Fruit或者其子类型的对象,但不能生产除了Fruit以外的对象。逆变类型首要用于函数参数的类型。

总结

Kotlin的协变与逆变通过关键字outin简化了泛型的使用,让类型转换更加灵活,同时保持了类型保险。这些特性让Kotlin的泛型更加易于领会和使用,降低了在Java中由于泛型让的纷乱通配符的使用。


本文由IT视界版权所有,禁止未经同意的情况下转发

文章标签: Java


热门