(изменяемая коллекция изменчива) возвращает true в Kotlin - PullRequest
0 голосов
/ 28 декабря 2018

Почему это происходит в 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 Immutable реализуют интерфейс MutableCollection, но вместо изменения элементов в коллекции он выдает UnsupportedOperationException

Это правда?и если да, то почему объекты неизменяемой коллекции реализуют интерфейс MutableCollection в Kotlin?

Это из-за того, что коллекции Kotlin наследуются от коллекций Java, и изменение методов (add, remove, ...) уже существует, и единственный путьчтобы избежать изменения коллекции, нужно переопределить ее и выдать исключение (даже если это правда, нет необходимости в объектах неизменяемой коллекции Kotlin для реализации интерфейса MutableCollection, потому что методы сбора java, изменяющие коллекцию, уже существуют и могут быть переопределены)?

1 Ответ

0 голосов
/ 28 декабря 2018

Нет, это не правильное объяснение.Этот код должен помочь вам понять, что происходит:

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 не являются действительно неизменными.У них просто нет какого-либо метода, позволяющего изменять их: они просто неизменяемые интерфейсы, которые предоставляют доступ только для чтения только из реально изменяемого списка.Если вы обманываете и преобразуете список в изменяемый список, то, если список на самом деле является списком Java, приведение будет успешным, но вы не можете знать, сможете ли вы на самом деле изменить их, как в Java: List может быть пустым списком, который нельзя изменить вообще, или списком без изменения размера, как в приведенном выше примере, или полностью изменяемым списком, таким как ArrayList.

...