kotlin: 泛型: 星投影/星号投射
一,功能
有些时候, 你可能想表示你并不知道类型参数的任何信息, 但是仍然希望能够安全地使用它.
这里所谓"安全地使用"是指, 对泛型类型定义一个类型投射, 要求这个泛型类型的所有的实体实例, 都是这个投射的子类型。
对于这个问题, Kotlin 提供了一种语法, 称为 星号投射(star-projection)
MutableList<Any?>包含的是任何类型的元素;
MutableList<*>是包含某种特定类型元素,但不知是哪个类型,所以不能写入;但可读取;
编译器将MutableList<*> 当做out投影的类型 MutableList<out Any?>,不能让她消费任何东西;
二,例子:
代码:
//处理按钮点击事件
binding.button1.setOnClickListener {
fun printList1(list: MutableList<*>) {
//list[0] = 3 //报错
println(list[0])
}
fun <T> printList2(list: MutableList<T>) {
//list[0] = 3 //报错
//list.add(3) //报错
println(list[0])
}
val list1 = mutableListOf<String>()
list1.add("string1")
list1.add("string2")
printList1(list1)
printList2(list1)
val list2 = mutableListOf<Int>()
list2.add(123)
list2.add(456)
printList1(list2)
printList2(list2)
}
运行结果:

三,例子:
代码:
//处理按钮点击事件
binding.button2.setOnClickListener {
class A<T>(val t: T, val t2: T, val t3: T)
class Apple(var name: String)
//使用类
val a1: A<*> = A(12, "String", Apple("苹果"))
val a2: A<Any?> = A(12, "String", Apple("苹果")) //和a1是一样的
println("=========================================")
val apple = a1.t3 //参数类型为Any
println(apple)
println("=========================================")
val apple2 = apple as Apple //强转成Apple类
println(apple2.name)
println("=========================================")
//使用数组
val list1: ArrayList<*> = arrayListOf("String", 1, 1.2f, Apple("苹果"))
//list1.add(true) //报错
for (item in list1) {
println(item)
}
println("===========* 等价于 out Any? 只能消费,不能生产 =================")
val list2: ArrayList<out Any?> = arrayListOf("String", 1, 1.2f, Apple("苹果"))
//list2.add("aaa") //报错
for (item in list2) {
println(item)
}
println("=========================================")
val list3: ArrayList<Any?> = arrayListOf("String", 1, 1.2f, Apple("苹果"))
list3.add(false)
for (item in list3) {
println(item)
}
println("=========================================")
}
运行结果:

浙公网安备 33010602011771号