kotlin - Kotlin 泛型中列表和可变列表的区别
问题描述
我最近研究了 kotlin 泛型,但我发现了一些奇怪的情况
interface MyItem
fun <ITEM : MyItem> bindItem(items: List<ITEM>?) {
val castedItem = items as List<MyItem>?
}
fun <ITEM : MyItem> bindItem2(items: MutableList<ITEM>?) {
val castedItem = items as MutableList<MyItem>?
}
仅在 MutableList 情况下,编译器会警告未选中的 Cast
如果有人知道这种情况,请告诉我。
解决方案
该List
接口具有声明站点协方差( <out T>
)。这意味着“向上转换”类型是安全的,因为 List 只输出项目。例如,如果您有 a List<Int>
,则将其用作 a 是安全的,List<Number>
因为 anInt
始终可以安全地转换为 a Number
。当您从列表中检索项目时,它们总是满足为 typeInt
或 supertype Number
。
MutableList
没有协变类型。它在声明站点是不变的。这意味着“向上转换”它的类型本质上是不安全的。例如,如果您将您的MutableList<Int>
转换为 a MutableList<Number>
,则使用该引用是不安全的 MutableList<Number>
,因为它会让您将 a 添加Float
到列表中。当原始引用用作 aMutableList<Int>
并尝试从中检索值时,它将获得 ClassCastException 以尝试使用Float
as a Int
。
在这种情况下,您可以安全地将MutableList
转换为协变类型,如下所示:
val castedItem = items as MutableList<out MyItem>?
但是MutableList
具有协变类型的 a 与 a 并没有什么不同List
,因此最好将其强制转换为 aList<MyItem>
以使意图更清晰。
推荐阅读
- python - Django:将自定义管理器添加到 auth.User 时不要创建迁移
- json - 在 javascript 中搜索 Json
- javascript - SuiteScript 无法读取未定义的属性“对话框”
- reactjs - 尝试使用 axios 发布正文 + 标题,但收到错误响应
- python - 无法将图像加载到 pygame 显示
- arrays - Clojure 创建具有默认值的二维数组
- python - pywinauto - 如何识别 GUI 对象
- ios - 有没有人看过或拥有 APNS 网络时序图?
- java - Java - 按子列表大小排序列表
- erlang - 正确使用 unicode 字符