Я всегда предполагал, что List в Kotlin неизменяемый, но, когда писал другой пост, я узнал, что технически он доступен только для чтения, а не неизменяем, так как на самом деле его можно изменить с помощью нескольких методов.

MutableList является подклассом List, и когда MutableList назначается List, он все еще может быть изменен с использованием ссылки на MutableList.

List также можно преобразовать в MutableList, а затем изменить. Это означает, что если вы передадите List в другой метод, есть вероятность, что ваш исходный список будет изменен.

«Безопасный» способ изменить List - использовать метод toMutableList(). Это создает копию оригинального List и возвращает MutableList.

Однако одноэлементный List, созданный с помощью listOf(), неизменен. Однако обратите внимание, что это не обнаруживается во время компиляции.

В стороне: эта разница по дизайну, из-за того, как Kotlin представляет List в Java. Если мы декомпилируем в Java, за кулисами произойдет вот что:

val list1 = listOf(1)
val list2 = listOf(1, 2)
...becomes...
@NotNull
private static final List list1 = CollectionsKt.listOf(1);
@NotNull
private static final List list2 = CollectionsKt.listOf(new Integer[]{1, 2});
...and CollectionsKt.listOf is...
public fun <T> listOf(element: T): List<T> = java.util.Collections.singletonList(element)

java.util.Collections.singletonList неизменен! Но поскольку многоэлементные списки создаются как массив, это фактически делает его изменяемым.

Как было сказано выше, если мы используем только List в коде Kotlin, а не назначаем его или приводим к MutableList, или передаем его на или из Java, то его можно смело назвать неизменяемым, поскольку в нем нет set() или add() методы.

Привет, если вам понравился этот пост, я подумал, что вы могли бы заинтересоваться членством в Medium, чтобы получить доступ к качественному контенту от авторов Medium, не стесняйтесь использовать мою реферальную ссылку! Вам также могут понравиться эти футболки с дизайном, вдохновленным кодом.