Kotlin 泛型:协变、逆变

1、Why?为什么需要泛型?

根本目的是在保证泛型类 类型安全的基础上,提高API的灵活性

2、How?如何保证类型安全?

Java处理型变的问题在于:把一切都推给了使用处,增加了不明所以的通配符,代码可读性变差。

Kotlin 使用in/out关键字,告诉编译器,我们定义的类是协变的还是逆变的,或者两者都不是(即不型变的)。这样就可以在声明处定义型变,使用处不需要额外的处理直接使用

3、Show?me the code

fun kotlinGeneric() {

    // 协变

    // Kotlin 中,默认方法签名为:List<out T>,类似 Java 中的 ? extends MySubString
    // 相当于,向编译器保障:out代表泛型类中,类型参数 T 只能存在于方法的返回值中,即是作为输出,
    // 因此,泛型类是生产者/协变的
    var data0:List<MySubString> = ArrayList<MyString>() // 错误
    var data1:List<MySubString> = ArrayList<MySubString>()
    var data2:List<MySubString> = ArrayList<MySubsubString>()

    // java 要达到上述目的,要这么写
//        List<? extends MySubString> consumerSuper2 = new ArrayList<MySubString>();
//        List<? extends MySubString> consumerSuper3 = new ArrayList<MySubsubString>();


    // 逆变
    // Kotlin 中,默认方法签名为:Comparable<in T>,类似 Java 中的 ? super MySubString
    var code0: Comparable<MySubString> = object : Comparable<MyString> {

        override fun compareTo(other: MyString): Int {
            return 1
        }
    }

    code0.compareTo(MyString()) // 错误
    code0.compareTo(MySubString())
    code0.compareTo(MySubsubString())

    // java 要达到上述目的,要这么写
//        List<? super MySubString> producerExtend0 = new ArrayList<Object>();
//        List<? super MySubString> producerExtend1 = new ArrayList<MyString>();
//        List<? super MySubString> producerExtend2 = new ArrayList<MySubString>();
}

open class MyString {

}

open class MySubString : MyString {
    constructor() : super()
}

open class MySubsubString : MySubString {
    constructor() : super()
}

参考:https://www.jianshu.com/p/0c2948f7e656

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容