为什么在科特林发生这样的事情:
val list: List<Int> = listOf(1, 2, 3)// Immutable list
if(list is MutableCollection<*>){// why this "if" condition is true?
println("is mutable")// this line is printed
(list as MutableCollection<Int>).add(4) // this results to java.lang.UnsupportedOperationException
}list is MutableCollection返回true,显示Kotlin不可变集合对象实现了MutableCollection接口,但是它没有更改集合中的项,而是抛出UnsupportedOperationException。
是真的吗?如果是,为什么不变的集合对象在Kotlin中实现MutableCollection接口?
这是因为Kotlin集合继承了Java集合并更改了方法(添加、删除、.)已经存在了,避免更改集合的唯一方法是重写它并抛出一个异常(即使这是真的,Kotlin不变的集合对象也不需要实现MutableCollection接口,因为java更改集合方法已经存在并且可以被覆盖)?
发布于 2018-12-27 22:43:33
不,这不是正确的解释。这段代码将帮助您理解正在发生的事情:
val list: List<Int> = listOf(1, 2, 3)
println("list class is = ${list::class.java}")
if(list is MutableCollection<*>) {
println("is mutable")
(list as MutableList<Int>)[0] = 42
println(list)
}输出是
list class is = class java.util.Arrays$ArrayList
is mutable
[42, 2, 3]因此,解释是listOf(1, 2, 3)返回数组$ArrayList列表,即通过执行Arrays.asList(1, 2, 3)返回的Arrays.asList(1, 2, 3)列表。它是一个可变的列表,但是您不能向它添加任何东西,因为它有固定的大小,因为它是由数组支持的。
Kotlin列表并不是一成不变的。他们只是没有任何允许对其进行变异的方法:它们只是不可变的接口,它们只公开实际可变列表的只读方法。如果您欺骗并将列表强制转换为可变列表,那么,如果列表实际上是一个Java列表,那么转换就会成功,但是您不知道您是否真的能够对它们进行变异,就像在Java中一样:一个列表可以是一个emptyList (它根本不能变异),或者一个不可调整的列表(如上面的例子),或者一个像ArrayList这样的完全可变的列表。
https://stackoverflow.com/questions/53951277
复制相似问题