Historia pytania:
Do Kotlin 1.9 obiekty typu object nie mogły być danymi — nie można było mieć singletonu, który automatycznie uzyskuje equals, hashCode, toString, jak klasy danych. Pojawienie się data object zniosło to ograniczenie. Teraz można utworzyć obiekt singleton z automatycznie generowanymi metodami, odpowiedni do wzorców wartości i podobnych do enum.
Problem:
Wcześniej, aby uzyskać poprawne equals(), hashCode(), toString() nawet dla obiektów singleton, trzeba było je ręcznie implementować lub używać innych sztuczek, co zwiększało BOILERPLATE i możliwość błędów.
Rozwiązanie:
Użyj data object dla obiektów, których instancja jest unikalna, a jednocześnie potrzebne jest standardowe zachowanie equals/hashCode/toString do przekazywania w kolekcjach, serializacji, porównywania i debugowania.
Przykład kodu:
data object NotAvailable fun checkStatus(status: Any) = when (status) { NotAvailable -> "Dane są niedostępne" else -> "Inny status" } val set = setOf(NotAvailable) println(NotAvailable in set) // true println(NotAvailable.toString()) // NotAvailable
Kluczowe cechy:
Czy data object może zawierać właściwości?
Może, ale tylko właściwości val bez backing field (ponieważ singleton nie powinien przechowywać żadnych danych)
data object Loading { val status: String get() = "Ładowanie..." }
Czym różni się data object od zwykłego obiektu pod względem equals?
Equals w zwykłym obiekcie sprawdza tylko tożsamość referencji, w data object porównywane jest zgodnie z kontraktem danych, ale w przypadku singletonu to zawsze ten sam obiekt. Jednak nadpisane equals/hashCode są bardziej przydatne dla kolekcji.
Czy można dziedziczyć po data object?
Nie, data object jest finalny, tak jak każdy obiekt w Kotlinie — nie można dziedziczyć.
Zamiast enum dla wszystkich stanów używano różnych data object. Po roku potrzebna była serializacja po nazwach, zaczęto ręcznie porównywać nazwy obiektów z typami.
Zalety:
Wady:
Dla wartości zwracanej z zapytania sieciowego używano data object dla specjalnych statusów: Loading, Empty, Error. Kod był zwięzły, wsparcie dla equals, hashCode, toString automatycznie.
Zalety:
Wady: