为何Kotlin中List<Int> is MutableList<Int>结果为true?
Kotlin中
listOf()返回的List为何会被判定为MutableList? 先看你给出的代码片段:
fun main() { val list = listOf(1, 2, 3) println(list is MutableList<Int>) // true }
你原本以为List<Int>类型的list不该被判定为MutableList<Int>,但编译器给出提示:
Condition 'list is MutableList' is always true.
下面逐一解答你的疑问:
为什么会出现这个结果?
Kotlin的listOf()函数在JVM平台有特殊实现逻辑:当传入的元素数量较少时,它会返回一个内部实现可变,但对外暴露只读List接口的实例(比如ArrayList或者Kotlin内部的ArraysUtilJVM.ArrayList)。这些类同时实现了List和MutableList接口,只是我们把它赋值给了List<Int>类型的变量,所以编译期只能看到只读接口,但运行时实际对象是可变类型的实现类。
is运算符的具体工作机制
is是运行时类型检查运算符,它判断的是变量指向的实际对象的类型,而非变量声明的静态类型。所以哪怕变量声明为List<Int>,只要实际对象实现了MutableList接口,list is MutableList<Int>就会返回true。- 编译器之所以提示“条件永远为真”,是因为它在编译期就知道
listOf()返回的实例必然是MutableList的实现类(这是标准库的既定实现),所以这个检查的结果是确定的。
这是向下转型吗?
这不是向下转型。向下转型是将父类型强制转换为子类型(比如list as MutableList<Int>),而这里只是用is做类型检查,确认实际对象是否属于子类型的实例。不过要注意,强行把List转为MutableList是不推荐的——List接口的设计目的就是对外提供只读访问,这种操作会破坏封装,可能导致意外的数据修改。
如何找到is运算符的相关实现?
is运算符的逻辑分两部分:
- 编译期的类型推断:可以查看Kotlin编译器源码中的
TypeChecker相关模块,这里处理编译期对类型检查的分析; - 运行时的检查:在JVM平台上,
is会被编译为Java的instanceof字节码指令,运行时实际执行的就是这个指令的逻辑。
内容的提问来源于stack exchange,提问作者Will B Chang
相关产品推荐
相关产品推荐

