ProgrammazioneSviluppatore Kotlin, Sviluppatore Android

Che cos'è un data object in Kotlin, come si utilizza e in cosa si differenzia da un normale object e da una data class?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Data object è un nuovo tipo di dichiarazione in Kotlin (dalla versione 1.9), che combina le caratteristiche di un oggetto singleton e di una data class. È progettato per casi in cui si desidera avere solo un'istanza di un oggetto e metodi generati automaticamente come equals, hashCode, toString (come in una data class).

Storia della domanda

In precedenza, per memorizzare entità uniche con metodi toString() ed equals() generati automaticamente, era necessario scrivere oggetti object con implementazioni manuali o utilizzare data class come compromesso con un'unica istanza (e non istanze multiple).

Problema

Gli oggetti singleton (object) non hanno equals, hashCode, toString generati automaticamente, mentre la data class presuppone molteplici istanze, il che non è adatto per modelli esaurienti simili a enum.

Soluzione

Con l'introduzione del data object, entrambe le problematiche possono essere risolte in modo conciso:

  • La classe può avere solo un'istanza (singleton).
  • Il compilatore genera i metodi necessari.

Esempio di codice:

data object LoadingState data object NoData println(LoadingState == LoadingState) // true println(LoadingState.toString()) // LoadingState

Caratteristiche chiave:

  • Sempre singleton — non può essere creata una seconda istanza.
  • Il compilatore aggiunge metodi equals, hashCode, toString come per le data class.
  • Particolarmente facile da usare insieme a sealed interface per la modellazione degli stati.

Domande imboscate.

Qual è la differenza tra data object e un normale object?

Solo il data object riceve l'autogenerazione dei metodi equals, hashCode, toString a livello di compilatore; un normale object utilizza implementazioni da Any (uguaglianza referenziale, toString limitato).

È possibile creare data object con parametri del costruttore?

No, un data object non può avere costruttori con parametri. È sempre senza parametri, poiché esiste solo un'istanza.

È possibile ereditare da un data object?

Sì, un data object può implementare interfacce, comprese le sealed interface, ed essere parte di gerarchie di stati.

Esempio:

sealed interface Result data object Success : Result data object Failure : Result

Errori tipici e anti-pattern

  • Tentativo di aggiungere campi costruttori in un data object (questo è vietato).
  • Utilizzo di data class dove si intende un'unica istanza.

Esempio dalla vita reale

Caso negativo

Un sviluppatore modella "nessun dato" come object NoData, poi confronta tramite equals() con un oggetto esterno e ottiene un risultato inaspettato (uguaglianza referenziale anziché sostanziale).

Pro:

  • Semplicità di dichiarazione.

Contro:

  • Comportamento inadeguato con equals/toString.

Caso positivo

Si utilizza un data object per stati di caricamento, l'uguaglianza e la stampa avvengono secondo le regole attese delle data class. Il modello di livello utilizza con affidabilità il pattern matching sugli stati.

Pro:

  • Generazione corretta dei metodi multipli.
  • Confronto sicuro e diagnostica.

Contro:

  • Il data object è apparso solo nelle nuove versioni di Kotlin — c'è il rischio di incompatibilità con vecchi progetti.