In Kotlin wordt ongewijzigdheid meestal begrepen als de onmogelijkheid om de status van een object na de creatie te veranderen. Dit wordt bereikt door het gebruik van val (onveranderlijke) eigenschappen, evenals door het creëren van klassen met initialisatie alleen in de constructor zonder methoden die interne gegevens kunnen wijzigen.
Kotlin biedt in tegenstelling tot Java een handige mechanismen voor het maken van immutable-classes via data class en collecties zoals List, Set, Map (die standaard onveranderlijk zijn). Maar het is belangrijk te begrijpen dat de basiscollecties in Kotlin alleen op het niveau van het interface onveranderlijk zijn, terwijl het object van de collectie kan worden gewijzigd als je deze omzet naar MutableList, enz.
Voorbeeld van de juiste ongewijzigdheid:
// Data class en val zorgen voor ongewijzigdheid data class User(val name: String, val age: Int) val user = User(name = "Ivan", age = 30) // user.name = "Sergey" // COMPILATIEFOUT
Voorbeeld van code die ongewijzigdheid schendt:
class User(var name: String, var age: Int) val user = User("Ivan", 30) user.name = "Sergey" // Wijziging van het object is mogelijk
Nuances:
val velden garandeert geen volledige ongewijzigdheid als de velden referentietypen zijn en hun interne status kan veranderen.val + onveranderlijke types (bijvoorbeeld val scores: List<Int>).Zijn de objecten van de data class met alleen val-eigenschappen volledig onveranderlijk (immutable)?
Antwoord: Nee, als de eigenschappen veranderbare objecten zijn (bijvoorbeeld val items: MutableList<Int>), kan de interne status worden gewijzigd.
Voorbeeld:
data class Group(val members: MutableList<String>) val group = Group(mutableListOf("Tom", "Jerry")) group.members.add("Spike") // interne status verandert
Verhaal
In het project werd een immutable
data classmet eenvaleigenschap van het typeMutableListgebruikt. Een van de ontwikkelaars verwachtte dat het object niet zou kunnen worden gewijzigd, maar een andere ontwikkelaar voegde nieuwe elementen aan de collectie toe. Dit leidde tot inconsistentie in de gegevens en moeilijk te identificeren bugs, toen twee threads tegelijkertijd de gedeelde lijst wijzigden.
Verhaal
Bij het doorgeven van een instantie van een klasse met een veranderbare collectie tussen de lagen van de applicatie, wijzigde één laag de inhoud zonder de andere laag te informeren. Dit leidde tot situaties waarin de UI niet op de hoogte was van de wijzigingen en werkte met ongeldige oorspronkelijke gegevens.
Verhaal
Een ontwikkelaar nam ten onrechte aan dat
Listin Kotlin altijd onveranderlijk was. In werkelijkheid werd er onder de motorkap een implementatie gebruikt die vanuit Java was doorgegeven (ArrayList), en de poging om de lijst te wijzigen leidde tot onverwachte gegevensverlies en bugs bij het werken met de database.