ProgrammingKotlin Developer, Android Developer

What is a data object in Kotlin, how to use it, and how does it differ from a regular object and a data class?

Pass interviews with Hintsage AI assistant

Answer.

Data object is a new type of declaration in Kotlin (since version 1.9) that combines the properties of a singleton object and a data class. It is designed for cases when you want to have only one instance of an object and automatically generated methods equals, hashCode, toString (like in a data class).

Background

Previously, to store unique entities with auto-generated toString() and equals() methods, developers had to write object with manual implementations or compromise by using data class with a single object (rather than instances).

Problem

Singleton objects (object) do not have auto-generated equals, hashCode, toString, while data class implies multiple instances, which is not suitable for exhaustive enum-like models.

Solution

With the emergence of data object, both tasks are solved succinctly:

  • The class can only be a single instance (singleton).
  • The compiler generates the necessary multimethods.

Code example:

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

Key features:

  • Always a singleton — a second instance cannot be created.
  • The compiler adds methods equals, hashCode, toString like for a data class.
  • Especially convenient to use together with sealed interface for modeling states.

Trick questions.

How does data object differ from a regular object?

Only data object receives auto-generation of equals, hashCode, toString methods at the compiler level; regular object uses implementations from Any (referential equality, limited toString).

Can a data object have constructor parameters?

No, a data object cannot have a constructor with parameters. It is always parameterless, as there exists only one instance.

Can a data object be inherited?

Yes, a data object can implement interfaces, including sealed interface, and be part of state hierarchies.

Example:

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

Typical mistakes and anti-patterns

  • Trying to add constructor fields to a data object (this is prohibited).
  • Using data class when a single instance is implied.

Real-life example

Negative case

A developer models "no data" as object NoData, then compares it with equals() to an external object and gets an unexpected result (referential comparison, not substantive).

Pros:

  • Simplicity of declaration.

Cons:

  • Inadequate behavior when using equals/toString.

Positive case

A data object is used for loading statuses, equality and printing happen according to expected data class rules. The model layer reliably uses pattern matching on states.

Pros:

  • Correct generation of multimethods.
  • Safe comparison and diagnostics.

Cons:

  • Data object appeared only in newer versions of Kotlin — there's a risk of incompatibility with older projects.