1

I have class that internally maintains a mutable list, and I want to provide an immutable view on this list. Currently I'm using the following:

/**The list that actually stores which element is at which position*/
private val list: MutableList<T> = ArrayList()

/**Immutable view of [list] to the outside.*/
val listView: List<T> get() = list.toList()

First question: Can this be done easier

Second question: How can I test that listView is actually immutable. I guess reflections are necessary?

Moritz Groß
  • 1,352
  • 12
  • 30
  • That's not an immutable view. It's a read-only view. Important distinction. The contents can be changing by whoever has access to the backing MutableList. – Tenfour04 Jun 23 '20 at 02:29

1 Answers1

0

If you only needed the compile-time type to be immutable, you could simply upcast your list:

val listView: List<T> get() = list

(Though if you checked and downcast that to MutableList, you could make changes — and those would affect the original list.)

However, if you want full immutability, that's tricky.  I don't think there are any general-purpose truly immutable lists in the Kotlin stdlib.

Although List and MutableList look like two different types, in Kotlin/JVM they both compile down to the same type in the bytecode, which is mutable.  And even in Kotlin, while Iterable.toList() does return a new list, the current implementation* actually gives a MutableList that's been upcast to List.  (Though mutating it wouldn't change the original list.)

Some third-party libraries provide truly immutable collections, though; see this question.

And to check whether a List is mutable, you could use a simple type check:

if (listView is MutableList)
    // …

No need to use reflection explicitly.  (A type check like that is considered to be implicit reflection.)

(* That can change, of course.  It's usually a mistake to read too much into the current code, if it's not backed up by the documentation.)

gidds
  • 16,558
  • 2
  • 19
  • 26