美文网首页
Kotlin 泛型:协变、逆变

Kotlin 泛型:协变、逆变

作者: Android那些事儿 | 来源:发表于2020-03-09 16:20 被阅读0次

    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

    相关文章

      网友评论

          本文标题:Kotlin 泛型:协变、逆变

          本文链接:https://www.haomeiwen.com/subject/ogmpdhtx.html