面试题答案
一键面试List<*>
与List<Any>
的区别:List<*>
:List<*>
表示一个类型未知的列表,它是类型投影的一种形式,被称为星投影。这里的*
代表任何类型。例如,如果一个列表实际存储的是Int
类型元素,List<*>
可以安全地引用它。它允许我们以只读方式访问列表元素,因为编译器不知道具体类型,所以写操作会受限,这有助于保证类型安全。例如,val list: List<Int> = listOf(1, 2, 3)
,可以赋值给val starList: List<*> = list
,但是不能进行像starList.add(4)
这样的操作(因为不知道具体类型,编译器会报错)。
List<Any>
:List<Any>
明确表示列表可以包含任何类型的对象,它不仅仅是只读的,还允许写入任何类型的对象到列表中。例如,如果有val anyList: MutableList<Any> = mutableListOf()
,可以执行anyList.add("string")
,anyList.add(1)
等操作。这可能会导致类型安全问题,因为如果后续代码假设列表中都是特定类型(比如Int
),而实际有其他类型(如String
),就会引发运行时错误。
- 类型参数的上界约束在这种场景下的使用:
- 类型参数的上界约束使用
where
关键字或者直接在类型参数声明处指定。例如,如果希望函数printList
能够处理任何类型的列表,但该类型必须是Number
的子类,可以这样定义函数:
fun <T : Number> printList(list: List<T>) { for (element in list) { println(element) } }
- 这里
<T : Number>
表示类型参数T
的上界是Number
,即T
必须是Number
或者Number
的子类。这样函数printList
就可以处理List<Int>
,List<Double>
等,但不能处理List<String>
。这使得函数在保证类型安全的同时,又有一定的通用性,只接受符合特定类型层次结构的列表,避免了处理不相关类型带来的错误。
- 类型参数的上界约束使用