As we know the List in Kotlin is immutable i.e. you can't do add and remove as below.
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
myList!!.add(10)
myList!!.remove(10)
}
}
But if we cast it to ArrayList as below, the add and remove works.
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
(myList!! as ArrayList).add(10)
(myList!! as ArrayList).remove(10)
}
}
I just thought this is odd, as myList is really a List, which is suppose to be immutable. And casting it, allow it to be altered.
Is what done above (casting to Array and modify the content) legitimate, or the language need to improve to disallow that?
There are a few different types of immutability:
One is mentioned from a separate SO answer here.
Readonly - you are NOT supposed to change it (Kotlin's List) but something may (cast to Mutable, or change from Java).
List
is just an interface that does not have mutating methods, but you can change the instance if you cast it to MutableList
.
Someone then goes on to comment that Kotlin chose to be readonly in order to use Java collections directly, so there is no overhead or conversion in using Java collections.
Kotlin List is readonly, not immutable. Other callers (Java for example) may change the list. Kotlin callers might cast the list and change it. There is no immutable protection.
Original Source: Kotlin and Immutable Collections?
Is it legitimate? Well, yes. There are uses cases in which that would make sense.
Is it a good idea? I think not, especially if you're talking about casting a list that was returned by some external library. The cast will fail if someone actually hands you some List
implementations that really is immutable and does not implement MutableList
. The fact that at the moment (Kotlin 1.0.2), all of Kotlin's Lists
are also MutableList
s doesn't mean that every List
you'll ever see in your code is also an MutableList
.
Right now if you use listOf() you'll get a List with all methods, which mutate the list, throwing java.lang.UnsupportedOperationException:
val list = listOf(1, 2)
val mlist = list as MutableList
mlist.add(3)
This throws:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)