collections kotlin
Updated Mon, 12 Sep 2022 07:50:33 GMT

Kotlin: exposing immutable list in API

I am new to Kotlin and am wrestling with the problem of returning immutable versions of internally mutable lists.

I reviewed the following 'Kotlin: Modifying (immutable) List through cast, is it legitimate?' and understand that immutable lists are really just read-only views which do not expose the modification methods.

I want to have a class which exposes an "immutable" List and still want to take advantage of Kotlins automatic getters (without having to provide all the boilerplate for getting the list or a member of the list)

Is the following a bad idea (or will it cause a problem that may be blocked in future releases)

class Foo {
  val names: List<String> = LinkedList;
  fun addName(name: String) {
    (names as LinkedList).add(name)

I am looking to allow (for example):

  val foo = Foo;

But still prevent the caller from modifying the internals of the class (at least as much as possible). For example removing elements or clearing the backing list.


The following works:

class Foo {
    private val _names: MutableList<String> = mutableListOf()
    val names: List<String>
        get() = _names.toList()
    fun addName(name: String) {

The toList means that if they cast it to a MutableList<String> and try to add to it they will get an UnsupportedOperationException, the _names field holds the real data, and external access is done via the names property

Comments (4)

  • +1 – Thanks jrtapsell, Yes I know I can maintain this second variable as well... but that wasn't sure if needed the additional clutter.. I think it also works like this: val name: List<String> = _names — Oct 14, 2017 at 15:53  
  • +0 – ... although that probably would not prevent the cast — Oct 14, 2017 at 15:59  
  • +0 – The names property just acts as a immutable view of _names, although it would be nice if the clutter could be reduced — Oct 14, 2017 at 16:04  
  • +0 – Using the backing field may simplify the code: link — Nov 06, 2017 at 15:43