En Kotlin, la inmutabilidad generalmente se entiende como la imposibilidad de cambiar el estado de un objeto después de su creación. Esto se logra a través del uso de propiedades val (inmutables), así como mediante la creación de clases que se inicializan solo en el constructor sin métodos que permitan modificar los datos internos.
Kotlin, a diferencia de Java, ofrece un mecanismo conveniente para crear clases inmutables a través de data class así como colecciones como List, Set, Map (que son inmutables por defecto). Pero es importante entender que en Kotlin, las colecciones básicas son inmutables solo a nivel de interfaz, y el objeto de la colección puede ser modificado si se convierte a MutableList, etc.
Ejemplo de inmutabilidad correcta:
// Data class y val aseguran la inmutabilidad data class User(val name: String, val age: Int) val user = User(name = "Ivan", age = 30) // user.name = "Sergey" // ERROR DE COMPILACIÓN
Ejemplo de código con violación de inmutabilidad:
class User(var name: String, var age: Int) val user = User("Ivan", 30) user.name = "Sergey" // Cambiar el objeto es posible
Matices:
val no garantiza la completa inmutabilidad si los campos son tipos de referencia y su estado interno cambia.val + tipos inmutables (por ejemplo, val scores: List<Int>).¿Son los objetos de la clase data class con solo propiedades val completamente inmutables (immutable)?
Respuesta: No, si las propiedades son objetos mutables (por ejemplo, val items: MutableList<Int>), se puede cambiar el estado interno.
Ejemplo:
data class Group(val members: MutableList<String>) val group = Group(mutableListOf("Tom", "Jerry")) group.members.add("Spike") // el estado interno cambia
Historia
En el proyecto se utilizó un
data classinmutable con una propiedadvalde tipoMutableList. Uno de los desarrolladores esperaba que el objeto no pudiera cambiar, sin embargo, otro desarrollador agregó nuevos elementos a la colección. Esto llevó a la inconsistencia de datos y errores difíciles de detectar, cuando dos hilos cambiaban paralelamente la lista compartida.
Historia
Al pasar una instancia de una clase con una colección mutable entre las capas de la aplicación, una capa modificaba el contenido, sin notificar a la otra capa. Esto provocó situaciones en las que la interfaz de usuario no conocía los cambios ocurridos y trabajaba con datos de entrada no válidos.
Historia
Un desarrollador pensó erróneamente que
Listen Kotlin siempre es inmutable. En realidad, bajo el capó se estaba utilizando una implementación pasada de Java (ArrayList), y el intento de modificar la lista resultó en una inesperada pérdida de datos y errores al trabajar con la base de datos.