In Kotlin, immutability usually means that the state of an object cannot be changed after it is created. This is achieved through the use of val (immutable) properties, as well as by creating classes that are initialized only in the constructor without methods to modify internal data.
Kotlin, unlike Java, offers a convenient mechanism for creating immutable classes via data class and collections like List, Set, Map (which are immutable by default). However, it's important to understand that the basic collections in Kotlin are immutable at the interface level only, while the collection object itself can be changed if cast to MutableList, etc.
Example of correct immutability:
// Data class and val ensure immutability data class User(val name: String, val age: Int) val user = User(name = "Ivan", age = 30) // user.name = "Sergey" // COMPILATION ERROR
Example of code violating immutability:
class User(var name: String, var age: Int) val user = User("Ivan", 30) user.name = "Sergey" // Object modification is possible
Nuances:
val fields does not guarantee complete immutability if the fields are reference types and their internal state changes.val + immutable types (e.g., val scores: List<Int>).Are objects of a data class with only val properties completely immutable?
Answer: No, if the properties are mutable objects (e.g., val items: MutableList<Int>), the internal state can be changed.
Example:
data class Group(val members: MutableList<String>) val group = Group(mutableListOf("Tom", "Jerry")) group.members.add("Spike") // internal state is changing
Story
An immutable
data classwith avalproperty of typeMutableListwas used in the project. One developer expected that the object could not be modified, however, another developer added new elements to the collection. This led to data inconsistency and hard-to-detect bugs when two threads modified a shared list simultaneously.
Story
When passing an instance of a class with a mutable collection between application layers, one layer modified the contents without notifying the other layer. This caused situations where the UI was unaware of the changes and worked with invalid initial data.
Story
A developer mistakenly believed that
Listin Kotlin is always immutable. In fact, an implementation passed from Java (ArrayList) was used under the hood, and attempts to modify the list led to unexpected data loss and bugs when interacting with the database.