ProgrammierungKotlin Entwickler

Wie funktionieren Data Objects (data object) in Kotlin, wofür sind sie notwendig, wie sind equals/hashCode/toString implementiert und wie unterscheiden sie sich von normalen objects und data classes?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Geschichte der Frage:

Vor Kotlin 1.9 konnten object-Objekte keine data sein – man konnte keinen Singleton haben, der automatisch equals, hashCode, toString erhält, wie data-Klassen. Mit der Einführung von data object wurde diese Einschränkung aufgehoben. Jetzt kann man ein Singleton-Objekt mit automatisch generierten Methoden erstellen, das für Value- und Enum-ähnliche Muster geeignet ist.

Problem:

Früher musste man für die korrekte equals(), hashCode(), toString() selbst bei Singleton-Objekten diese manuell implementieren oder andere Tricks verwenden, was den BOILERPLATE erhöhte und die Fehleranfälligkeit vergrößerte.

Lösung:

Verwenden Sie data object für Objekte, deren Instanz einzigartig ist, und für die ein Standardverhalten von equals/hashCode/toString erforderlich ist, um sie in Sammlungen zu übergeben, zu serialisieren, zu vergleichen und zu debuggen.

Beispielcode:

data object NotAvailable fun checkStatus(status: Any) = when (status) { NotAvailable -> "Daten fehlen" else -> "Anderer Status" } val set = setOf(NotAvailable) println(NotAvailable in set) // true println(NotAvailable.toString()) // NotAvailable

Schlüsselfunktionen:

  • Data object implementiert equals/hashCode/toString gemäß dem Vertrag von data class
  • Es ist ein Singleton-Objekt (einzige Instanz)
  • Geeignet für value-ähnliche oder enum-ähnliche Muster ohne Daten

Fangfragen.

Können data objects Eigenschaften enthalten?

Ja, aber nur val-Eigenschaften ohne backing field (da es in einem Singleton nichts gespeichert sein sollte).

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

Wie unterscheidet sich data object von einem normalen object in Bezug auf equals?

Equals bei einem normalen object prüft nur die Referenzidentität, bei data object wird der data-Vertrag verglichen, aber im Fall eines Singletons ist es immer dasselbe Objekt. Dennoch ist das überschriebenes equals/hashCode für Sammlungen nützlicher.

Kann man von data object erben?

Nein, data object ist final, wie jedes object in Kotlin – Vererbung ist nicht möglich.

Typische Fehler und Anti-Patterns

  • Data object anstelle von enum verwenden, wenn es mehrere Objekte gibt
  • Data object verwenden, um zu versuchen, Daten zu speichern – ist nicht erlaubt
  • Nicht berücksichtigen, dass Gleichheit immer referenziell ist, aber in Sammlungen nach Wert vorgesehen ist

Beispiel aus dem Leben

Negativer Fall

Anstelle von enum für alle Zustände wurden verschiedene data objects verwendet. Nach einem Jahr benötigte man eine Serialisierung der Namen, und musste manuell die Objekt-Namen mit den Typen abgleichen.

Vorteile:

  • Einfache Initialisierung

Nachteile:

  • Überflüssige Umgehungslösungen für die Serialisierung, Fehler beim Abgleich

Positiver Fall

Für den Rückgabewert einer Netzwerkabfrage wurden data objects für spezielle Status verwendet: Loading, Empty, Error. So ist der Code kompakt, Unterstützung für equals, hashCode, toString automatisch.

Vorteile:

  • Praktisch für Überprüfungen in Sammlungen
  • Schönes Logging

Nachteile:

  • Keine variablen Eigenschaften möglich, nur val-lazy