kotlin - (不可变集合是可变的)在 Kotlin 中返回 true

标签 kotlin immutable-collections

为什么这会在 Kotlin 中发生:

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 接口(interface),但它没有更改集合中的项目而是抛出 UnsupportedOperationException/p>

这是真的吗?如果是,为什么不可变集合对象在 Kotlin 中实现 MutableCollection 接口(interface)?

是不是因为 Kotlin 集合继承自 Java 集合并且更改方法(添加、删除等)已经存在并且避免更改集合的唯一方法是覆盖它并抛出异常(即使这是真的Kotlin 不可变集合对象没有必要实现 MutableCollection 接口(interface),因为 java 改变集合方法已经存在并且可以被覆盖)?

最佳答案

不,这不是正确的解释。这段代码应该可以帮助您了解发生了什么:

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) 返回一个 Arrays$ArrayList 列表,即在 Java 中执行 Arrays.asList(1 , 2, 3)。它是一个可变列表,但您不能向其中添加任何内容,因为它具有固定大小,因为它由数组支持。

Kotlin 列表并不是真正不可变的。它们只是没有任何允许改变它们的方法:它们只是不可变接口(interface),只公开实际可变列表的只读方法。如果您欺骗并将列表转换为可变列表,那么,如果该列表实际上是 Java List,则转换会成功,但您无法知道您是否真的能够改变它们,就像在 Java 中一样:一个列表可以是一个空列表,它根本不能被改变,或者是一个不可调整大小的列表,如上面的例子,或者一个完全可变的列表,如 ArrayList。

关于kotlin - (不可变集合是可变的)在 Kotlin 中返回 true,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53951277/

相关文章:

immutability - Kotlin 中带有 val 的循环引用

kotlin - mock 验证 lambda 在 mock 中传递

scala - 以更不可变的方式解决此练习的更好方法是什么?

android - 使用 MVVM 在 Android 中验证权限的优雅方式

java - Android:编辑以编程方式添加的 View

android - 如果 MutableList 为空,如何更改 TextView 的可见性? (安卓/ Kotlin )

c# - 创建编译时未知类型的 ImmutableList

java - 这是在构建器对象中创建空集的最佳方法

javascript - 如何从不可变树中获取更改的树,最大限度地重用节点

c# - BCL 不可变集合 : equality is non-symmetric