(imutable collection is mutable) returns true in Kotlin

我的梦境 提交于 2021-01-27 12:55:18

问题


Why this is happening in 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 that shows Kotlin Immutable collection objects implements MutableCollection interface but instead of changing items in collection it throws UnsupportedOperationException

Is it true? and if yes why Immutable collection objects implement MutableCollection interface in Kotlin?

Is it because of Kotlin collections inherit from Java Collections and altering methods (add, remove, ...) already is there and the only way to avoid altering collection is to override it and throw an exception (even if this is true it is not necessary for Kotlin immutable collection objects to implement MutableCollection interface because java altering collection methods already are there and can be overridden)?


回答1:


No, that's not the correct explanation. This code should help you understand what's going on:

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)
}

The output is

list class is = class java.util.Arrays$ArrayList
is mutable
[42, 2, 3]

So, the explanation is that listOf(1, 2, 3) returns an Arrays$ArrayList list, i.e. the list that would be returned in Java by doing Arrays.asList(1, 2, 3). It is a mutable list, but you can't add anything to it, because it has a fixed size, since it's backed by an array.

Kotlin lists aren't truly immutable. They just don't have any method allowing to mutate them: they're just immutable interfaces that only expose the readonly methods of an actually mutable list. If you cheat and cast the list to a mutable list, then, if the list is in fact a Java List, the cast will succeed, but you can't know if you're actually be able to mutate them, just like in Java: a List could be an emptyList, which can't be mutated at all, or a non-resizable list as in the above example, or a fully mutable list like an ArrayList.



来源:https://stackoverflow.com/questions/53951277/imutable-collection-is-mutable-returns-true-in-kotlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!