To class, or to data class, that is the question

Patxi Bocos
2 min readNov 15, 2019

Whenever we write a new class in Kotlin, we may feel tempted about defining as a data class. But should every class which is a data holder be a data class? I don’t think so. During the last months I have seen suggestions in PRs such as “make this class a data class?”.

Kotlin data class

Let’s see first what is Kotlin compiler generating for free when we declare a data class.

  • equals() / hashCode() => nothing fancy here, just the implementation for this well known functions.
  • toString() => a nice to see String representation of the class.
  • componentN() functions => functions that are implicitly called when using destructuring declarations.
  • copy() => allows making a copy of an object (favoring inmutability!).

Are you using any of this functions? If the answer is no then there is no need to define your class as a data class.

But what if you are just interested on one of them? There is no way to tell Kotlin to just generate equals/hashCode for example. If you are coming from Java, you will have probably heard about Lombok, which allows annotating a class to generate functions as described above (and more).

If you just want your class to have an equals, hashCode or toString implementation, you can rely on your prefered IDE to automatically implement it for you.

Key differences

Kotlin data class cannot be declared as open, but they can extend a class:

And is it possible to override any of the declared functions by a data class? Yes, except componentN functions. This is because this functions are declared as final, but some thing we can do (just for fun), is declare extra componentN functions, so for example:

In the above code we are defining a component2 function which allows us doing this destructuration:

val (name, upperCaseName) = Language(“Spanish”)

this doesn’t probably make any sense but is good to know that is possible 🙂

And as we have overwritten the equals method, this comparison will return true:

Language("spanish") == Language("SPANISH") // true

Conclusion

Don’t write data classes everywhere without considering first if you are going to use any of its features 😉

Patxi Bocos

Impure developer and functional programming enthusiast