(不可变集合是可变的)returns 在 Kotlin 中为真
(imutable collection is mutable) returns true in Kotlin
为什么在 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
returns true 表明 Kotlin 不可变集合对象实现了 MutableCollection
接口,但它没有更改集合中的项目而是抛出 UnsupportedOperationException
这是真的吗?如果是,为什么不可变集合对象在 Kotlin 中实现 MutableCollection
接口?
是因为 Kotlin 集合继承自 Java 集合和更改方法(添加、删除等)已经存在,避免更改集合的唯一方法是覆盖它并抛出异常(即使这是真的,Kotlin 不可变集合对象也没有必要实现 MutableCollection
接口,因为 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)
returns 一个 Arrays$ArrayList 列表,即通过 Arrays.asList(1, 2, 3)
在 Java 中返回的列表。它是一个可变列表,但是你不能向它添加任何东西,因为它有一个固定的大小,因为它有一个数组支持。
Kotlin 列表并非真正不可变。它们只是没有任何允许改变它们的方法:它们只是不可变接口,只公开实际可变列表的只读方法。如果你作弊并将列表转换为可变列表,那么,如果列表实际上是一个 Java 列表,转换将成功,但你不知道你是否真的能够改变它们,就像在 Java 中一样:一个列表可以是一个空列表,它根本不能被改变,或者是一个不可调整大小的列表,如上面的例子,或者一个完全可变的列表,如 ArrayList。
为什么在 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
returns true 表明 Kotlin 不可变集合对象实现了 MutableCollection
接口,但它没有更改集合中的项目而是抛出 UnsupportedOperationException
这是真的吗?如果是,为什么不可变集合对象在 Kotlin 中实现 MutableCollection
接口?
是因为 Kotlin 集合继承自 Java 集合和更改方法(添加、删除等)已经存在,避免更改集合的唯一方法是覆盖它并抛出异常(即使这是真的,Kotlin 不可变集合对象也没有必要实现 MutableCollection
接口,因为 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)
returns 一个 Arrays$ArrayList 列表,即通过 Arrays.asList(1, 2, 3)
在 Java 中返回的列表。它是一个可变列表,但是你不能向它添加任何东西,因为它有一个固定的大小,因为它有一个数组支持。
Kotlin 列表并非真正不可变。它们只是没有任何允许改变它们的方法:它们只是不可变接口,只公开实际可变列表的只读方法。如果你作弊并将列表转换为可变列表,那么,如果列表实际上是一个 Java 列表,转换将成功,但你不知道你是否真的能够改变它们,就像在 Java 中一样:一个列表可以是一个空列表,它根本不能被改变,或者是一个不可调整大小的列表,如上面的例子,或者一个完全可变的列表,如 ArrayList。