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)
        }

运行结果:

image

三,例子:

代码:

        //处理按钮点击事件
        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("=========================================")
        }

运行结果:

image

 

posted @ 2025-09-06 08:38  刘宏缔的架构森林  阅读(15)  评论(0)    收藏  举报