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;
println(foo.names.size)
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) {
_names.add(name)
}
}
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
Define mutable list as a private property with underscore (a kind of "field" in Kotlin) and expose it through another public read-only property.
If the "field" is read-only this will do the trick (suggested by @JWT):
class Foo {
private val _names: MutableList<String> = mutableListOf()
val names: List<String> = _names
fun addName(name: String) {
_names.add(name)
}
}
If the "field" might be reassigned, it will require to define getter as a function (note var _names
):
class Foo2 {
private var _names: MutableList<String> = mutableListOf()
val names: List<String>
get() = _names
fun addName(name: String) {
_names.add(name)
}
fun reset() {
_names = mutableListOf()
}
}
Tests are available here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With