ProgrammatieKotlin ontwikkelaar

Hoe werken Data Objects (data object) in Kotlin, waarvoor zijn ze nodig, hoe zijn equals/hashCode/toString geïmplementeerd, en wat zijn de verschillen met gewone objecten en data classes?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

Geschiedenis van de vraag:

Tot Kotlin 1.9 konden object-objecten geen data zijn — je kon geen singleton hebben die automatisch equals, hashCode, toString kreeg, zoals data-classes. Met de komst van data object is deze beperking opgeheven. Nu kun je een singleton-object creëren met automatisch gegenereerde methoden, geschikt voor Value en Enum-achtige patronen.

Probleem:

Eerder moest je voor correcte equals(), hashCode(), toString() zelfs voor singleton-objecten deze handmatig implementeren of andere trucs gebruiken, wat de BOILERPLATE en de kans op fouten verhoogde.

Oplossing:

Gebruik data object voor objecten waarvan de instantie uniek is, en waar standaardgedrag voor equals/hashCode/toString nodig is voor doorgegeven aan collecties, serialisatie, vergelijking en debugging.

Code voorbeeld:

data object NotAvailable fun checkStatus(status: Any) = when (status) { NotAvailable -> "Data ontbreekt" else -> "Andere status" } val set = setOf(NotAvailable) println(NotAvailable in set) // true println(NotAvailable.toString()) // NotAvailable

Belangrijke kenmerken:

  • Data object implementeert equals/hashCode/toString volgens het contract van data class
  • Dit is een singleton-object (één enkele instantie)
  • Geschikt voor value-achtige of enum-achtige patronen zonder gegevens

Vragen met een valstrik.

Kunnen data object eigenschappen bevatten?

Ja, maar alleen val-eigenschappen zonder backing field (aangezien er niets opgeslagen mag worden in een singleton)

data object Loading { val status: String get() = "Loading..." }

Wat is het verschil tussen een data object en een gewoon object qua equals?

Equals van een gewoon object controleert alleen de referentie-identiteit, bij data object wordt het data-contract vergeleken, maar in het geval van singleton is dit altijd hetzelfde object. Echter, de overschreven equals/hashCode zijn nuttiger voor collecties.

Kun je erven van een data object?

Nee, data object is finale, net als elke object in Kotlin — je kunt er niet van erven.

Typische fouten en anti-patronen

  • Data object gebruiken in plaats van enum, wanneer er meerdere objecten zijn
  • Data object gebruiken terwijl je probeert gegevens op te slaan — dit is niet toegestaan
  • Niet inzien dat gelijkheid altijd referentieel is, maar wordt voorzien voor collecties op waarde

Voorbeeld uit het leven

Negatieve case

In plaats van enum voor alle staten werden verschillende data objecten gebruikt. Na een jaar was er behoefte aan serialisatie op strings, en moesten ze handmatig de namen van objecten aan de types koppelen.

Voordelen:

  • Gemakkelijke initialisatie

Nadelen:

  • Overbodige hacks voor serialisatie, fout in de koppeling

Positieve case

Voor de geretourneerde waarde van een netwerkverzoek werden data objecten gebruikt voor speciale statussen: Loading, Empty, Error. Hierdoor is de code compact, en de ondersteuning van equals, hashCode, toString is automatisch.

Voordelen:

  • Handig voor controle in collecties
  • Mooie logging

Nadelen:

  • Geen variabele eigenschappen kunnen worden toegevoegd, alleen val-lazy