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()
}
网友评论