Historique de la question :
En Java, l'immuabilité des collections est atteinte par le biais d'enveloppements tels que Collections.unmodifiableList() et la création de classes immuables manuellement (champs final, absence de setters). Dans la pratique du développement Android et serveur, cela est devenu coûteux et peu pratique, et la sécurité des threads ainsi que la prévisibilité des données étaient perdues.
Problème :
Les collections Java ne sont pas sécurisées par défaut, il est toujours possible d'obtenir une référence et de modifier l'objet. Cela complique le contrôle d'immuabilité, particulièrement dans des environnements multithreads, et entraîne des bugs difficiles à détecter.
Solution :
Kotlin a été dès le départ conçu avec une séparation des collections en read-only et mutable, et la création d'objets véritablement immuables est devenue plus simple grâce à val, data class et List/Set/Map sans le préfixe mutable. Par-dessus cela, l'utilisation de la copie via des méthodes copy().
Exemple de code :
val nums: List<Int> = listOf(1, 2, 3) // liste immuable // nums.add(4) // erreur de compilation val user = User(name = "Alex", age = 30) val updated = user.copy(age = 31) // Exemple avec un map immuable val state: Map<String, Int> = mapOf("a" to 1, "b" to 2)
Caractéristiques clés :
val garantit-il une immuabilité absolue de l'objet imbriqué ?
Non ! val garantit seulement que la variable ne peut pas pointer vers un autre objet, mais les champs de l'objet peuvent être modifiés (si les propriétés internes sont var).
Peut-on obtenir un objet mutable à partir d'une collection read-only ?
Oui — si la collection contient un objet mutable, il est possible de modifier son état, malgré l'interface read-only de la collection.
data class User(var name: String) val users: List<User> = listOf(User("Vasya")) users[0].name = "Petya" // permis
Que se passera-t-il lors de la conversion de List<Int> en MutableList<Int> via as ?
Cela se compilera, mais conduira à une ClassCastException à l'exécution si le type d'origine était une interface read-only.
Une application Android stocke l'état dans val List<User>, le considérant comme immuable. L'un des développeurs modifie user.name. Dans un autre fragment, la liste mise à jour montre alors des données incohérentes — le bug apparaît dans la version finale.
Avantages :
Inconvénients :
Utilisation de classes de données immuables uniquement avec des champs val, filtrage de l'accès aux objets imbriqués, mise à jour de l'état via copy().
Avantages :
Inconvénients :