ProgrammationDéveloppeur Kotlin

Comment fonctionnent les Data Objects (objet de données) en Kotlin, à quoi servent-ils, comment sont implémentés equals/hashCode/toString, et en quoi diffèrent-ils des objets normaux et des data classes ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Historique de la question :

Avant Kotlin 1.9, les objets object ne pouvaient pas être des données - vous ne pouviez pas avoir de singleton obtenant automatiquement equals, hashCode, toString, comme les data classes. Avec l'apparition de data object, cette restriction a été levée. Vous pouvez maintenant créer un objet singleton avec des méthodes générées automatiquement, adapté aux modèles Value et Enum-like.

Problème :

Auparavant, pour obtenir un equals(), hashCode(), toString() correct même pour les objets singleton, il fallait les implémenter manuellement ou utiliser d'autres astuces, ce qui augmentait le BOILERPLATE et le risque d'erreur.

Solution :

Utilisez un data object pour les objets dont l'instance est unique et qui nécessitent un comportement standard pour equals/hashCode/toString afin de pouvoir les transmettre dans des collections, les sérialiser, les comparer et déboguer.

Exemple de code :

data object NotAvailable fun checkStatus(status: Any) = when (status) { NotAvailable -> "Les données sont manquantes" else -> "Autre statut" } val set = setOf(NotAvailable) println(NotAvailable in set) // true println(NotAvailable.toString()) // NotAvailable

Caractéristiques clés :

  • Le Data object implémente equals/hashCode/toString selon le contrat de data class
  • C'est un objet singleton (une seule instance)
  • Convient aux modèles comme value ou enum sans données

Questions pièges.

Les data objects peuvent-ils contenir des propriétés ?

Ils peuvent, mais uniquement des propriétés val sans champ de sauvegarde (puisqu'aucune donnée ne doit être stockée dans un singleton)

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

En quoi le data object diffère-t-il d'un objet normal en matière d'égalité ?

L'égalité d'un objet normal ne vérifie que l'identité de référence, tandis que celle d'un data object compare le contrat de données, mais dans le cas d'un singleton, c'est toujours le même objet. Cependant, equals/hashCode redéfinis sont plus utiles pour les collections.

Peut-on hériter d'un data object ?

Non, le data object est final, tout comme tout objet en Kotlin - il n'est pas possible d'hériter.

Erreurs typiques et anti-modèles

  • Utiliser un data object au lieu d'un enum lorsque plusieurs objets existent
  • Utiliser un data object en essayant de stocker des données - cela est interdit
  • Ne pas tenir compte que l'égalité est toujours référentielle, mais que les collections sont considérées par valeur

Exemple de la vie réelle

Cas négatif

Au lieu d'un enum pour tous les états, des data objects différents ont été utilisés. Un an plus tard, une sérialisation par chaînes était nécessaire, et il a fallu associer manuellement les noms des objets aux types.

Avantages :

  • Initialisation facile

Inconvénients :

  • Beaucoups de béquilles pour la sérialisation, erreur dans l'association

Cas positif

Pour la valeur de retour d'une requête réseau, un data object a été utilisé pour des statuts spéciaux : Loading, Empty, Error. Ainsi, le code est compact, et equals, hashCode, toString sont gérés automatiquement.

Avantages :

  • Pratique pour les vérifications dans les collections
  • Journalisation élégante

Inconvénients :

  • Impossible d'ajouter des propriétés variables, uniquement des val-lazy