Давайте запустим эксперимент:
class Foo {
@Test
fun foo() {
val items = mutableListOf("A")
run(items)
Thread.sleep(1000)
items.add("B")
println("Foo")
Thread.sleep(2000)
}
fun run(items: List<String>) {
thread(start = true) {
println("Run ${items.count()}")
Thread.sleep(2000)
println("Run ${items.count()}")
}
}
}
В этом тестовом примере будет создан изменяемый список из 1 элемента, затем он передаст ссылку на этот список в метод, тип которого предназначен для неизменяемого списка.
Этот метод, называемый run, будет отображать длину списка.
Вне метода run новый список будет добавлен к списку.
Sleep были добавлены, убедитесь, чтодобавление в список происходит после первого оператора run, но перед вторым оператором print.
Давайте рассмотрим вывод:
Run 1
Foo
Run 2
Как мы видим, содержимое списка действительно изменилось, дажехотя run занял неизменный список.
Это потому, что MutableList и List являются просто интерфейсами, и все реализации MutableList также реализуют List.
Когда Kotlin ссылается на изменяемый и неизменяемый объект, он просто указывает, присутствуют ли методы для изменения коллекции, а не может ли быть изменено содержимое.
Так что если вы берете в список методиспользуя List в качестве типа параметра, тогда да, содержимое может изменяться, если оно изменяется другим потоком, если это вызывает озабоченность, то сделайте копию списка, как первое, что делает ваш метод.