Kotlin:通过强制转换修改(不可变)列表,这是合法的吗?

时间:2016-06-21 23:55:33

标签: collections kotlin

我们知道Kotlin中的List是不可变的,即你不能像下面那样添加和删除。

class TempClass {
    var myList: List<Int>? = null
    fun doSomething() {
        myList = ArrayList<Int>()
        myList!!.add(10)
        myList!!.remove(10)
    }
}

但是如果我们将其转换为ArrayList,则添加和删除工作。

class TempClass {
    var myList: List<Int>? = null
    fun doSomething() {
        myList = ArrayList<Int>()
        (myList!! as ArrayList).add(10)
        (myList!! as ArrayList).remove(10)
    }
}

我只是觉得这很奇怪,因为myList实际上是一个List,它假设是不可变的。并且施放它,允许它被改变。

上面做了什么(转换为Array并修改内容)是合法的,还是语言需要改进以禁止它?

3 个答案:

答案 0 :(得分:6)

有一些不同类型的不变性:

从单独的SO回答here中提到了一个。

  

Readonly - 你不应该改变它(Kotlin的列表),但有些东西可能(强制转换为Mutable,或者从Java改变)。

List只是一个没有变异方法的接口,但如果将其转换为MutableList,则可以更改该实例。

然后有人继续评论Kotlin为了直接使用Java集合而选择只读,因此使用Java集合没有任何开销或转换。

Kotlin List是readonly,而不是一成不变的。其他调用者(例如Java)可能会更改列表。 Kotlin调用者可能会列出并更改它。没有不可改变的保护。

原始来源:Kotlin and Immutable Collections?

答案 1 :(得分:1)

合法吗?嗯,是。有些用例会有意义。

这是个好主意吗?我想不是,特别是如果你正在讨论一些由外部库返回的列表。如果有人实际上提供了一些真正不可变且不实现List的{​​{1}}实现,则转换将失败。目前(Kotlin 1.0.2),Kotlin MutableList的所有ListsMutableList并不意味着每个List你&#39;我们的代码中也会看到MutableList

答案 2 :(得分:1)

现在,如果您使用 listOf(),您将获得一个包含所有方法的List,这会改变列表,抛出java.lang.UnsupportedOperationException:

val list = listOf(1, 2)

val mlist = list as MutableList

mlist.add(3)

这引发:

Exception in thread "main" java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(AbstractList.java:148)