Data classes
Data classes in Kotlin are classes whose main purpose is to hold data. Data classes come automatically with additional member functions that allow you to print an instance to readable output, compare instances, copy instances, and more. Data classes are marked with data
:
The compiler automatically derives the following members from all properties declared in the primary constructor:
.equals()
/.hashCode()
pair.toString()
of the form"User(name=John, age=42)"
.componentN()
functions corresponding to the properties in their order of declaration..copy()
function (see below).
To ensure consistency and meaningful behavior of the generated code, data classes have to fulfill the following requirements:
The primary constructor needs to have at least one parameter.
All primary constructor parameters need to be marked as
val
orvar
.Data classes cannot be abstract, open, sealed, or inner.
Additionally, the generation of data class members follows these rules with regard to the members' inheritance:
If there are explicit implementations of
.equals()
,.hashCode()
, or.toString()
in the data class body orfinal
implementations in a superclass, then these functions are not generated, and the existing implementations are used.If a supertype has
.componentN()
functions that areopen
and return compatible types, the corresponding functions are generated for the data class and override those of the supertype. If the functions of the supertype cannot be overridden due to incompatible signatures or due to their being final, an error is reported.Providing explicit implementations for the
.componentN()
and.copy()
functions is not allowed.
Data classes may extend other classes (see Sealed classes for examples).
Properties declared in the class body
The compiler only uses the properties defined inside the primary constructor for the automatically generated functions. To exclude a property from the generated implementations, declare it inside the class body:
In this example, only the name
property can be used inside the .toString()
, .equals()
, .hashCode()
, and .copy()
implementations, and there is only one component function .component1()
. The age
property can't be used inside the .toString()
, .equals()
, .hashCode()
, and .copy()
implementations because it's declared inside the class body. If two Person
objects have different ages but the same name
, then they are treated as equal. This is because the .equals()
function can only check for equality of the name
property. For example:
Copying
Use the .copy()
function to copy an object, allowing you to alter some of its properties while keeping the rest unchanged. The implementation of this function for the User
class above would be as follows:
You can then write the following:
Data classes and destructuring declarations
Component functions generated for data classes make it possible to use them in destructuring declarations:
Standard data classes
The standard library provides the Pair
and Triple
classes. In most cases, though, named data classes are a better design choice because they make the code easier to read by providing meaningful names for the properties.