Kotlin Data Classes (original) (raw)

Last Updated : 08 Jun, 2025

In Kotlin, we often create classes just to hold data. These are called data classes, and they are marked with the data keyword. Kotlin automatically creates some useful functions for these classes, so you don’t have to write them yourself.

What Is a Data Class?

A data class is a class that holds data. Kotlin automatically provides useful methods like:

  1. equals() – to check if two objects are equal
  2. hashCode() – used when storing objects in hash-based collections
  3. toString() – to get a string version of the object
  4. copy() – to copy an object with some modified values

**Example:

data class Student(val name: String, val rollNo: Int)

When you create this class, Kotlin automatically gives it the above functions using the primary constructor parameters (name and rollNo in this case).

Rules for Creating a Data Class -

To make sure data classes work correctly, Kotlin has some rules:

  1. The primary constructor must have at least one parameter.
  2. All primary constructor parameters must be marked with val or var.
  3. A data class cannot be abstract, open, sealed, or inner.
  4. A data class can only implement interfaces, not extend other classes.

Using toString()

The toString() function gives you a string showing all the values in the primary constructor.

**Example:

Kotlin `

data class Person(val name: String, val roll: Int, val height: Int)

fun main() { val man = Person("man", 1, 50) println(man) }

`

**Output:

Person(name=man, roll=1, height=50)

**Note: But if you define properties inside the class body (not in the constructor), toString() won’t include them.

**Example:

Kotlin `

data class Person(val name: String) { var height: Int = 70 }

fun main() { val man = Person("manish") println(man) println(man.height) }

`

**Output:

Person(name=manish)
70

Here _height is not used by the toString() function .

Using copy()

Sometimes, you want to make a copy of an object, but change just one or two values. That’s where the copy() function is useful.

**Properties of copy()

**Declaration of copy()

fun copy(name: String = this.x, age: Int = this.y) = user(x, y)

where **user is a data class : user(String, Int) .

**Example

Kotlin `

data class Person(val name: String, val age: Int) { var height: Int = 100 }

fun main() { val man1 = Person("manish", 18) man1.height = 100

val man2 = man1.copy(name = "rahul")
man2.height = 90

val man3 = man1.copy()
man3.height = 110

println("${man1.name}, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>m</mi><mi>a</mi><mi>n</mi><mn>1.</mn><mi>a</mi><mi>g</mi><mi>e</mi></mrow><mi>h</mi><mi>a</mi><mi>s</mi></mrow><annotation encoding="application/x-tex">{man1.age} has </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">man</span><span class="mord">1.</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span></span><span class="mord mathnormal">ha</span><span class="mord mathnormal">s</span></span></span></span>{man1.height} cm height")
println("${man2.name}, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>m</mi><mi>a</mi><mi>n</mi><mn>2.</mn><mi>a</mi><mi>g</mi><mi>e</mi></mrow><mi>h</mi><mi>a</mi><mi>s</mi></mrow><annotation encoding="application/x-tex">{man2.age} has </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">man</span><span class="mord">2.</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span></span><span class="mord mathnormal">ha</span><span class="mord mathnormal">s</span></span></span></span>{man2.height} cm height")
println("${man3.name}, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>m</mi><mi>a</mi><mi>n</mi><mn>3.</mn><mi>a</mi><mi>g</mi><mi>e</mi></mrow><mi>h</mi><mi>a</mi><mi>s</mi></mrow><annotation encoding="application/x-tex">{man3.age} has </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">man</span><span class="mord">3.</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span></span><span class="mord mathnormal">ha</span><span class="mord mathnormal">s</span></span></span></span>{man3.height} cm height")

}

`

**Output:

manish, 18 has 100 cm height
rahul, 18 has 90 cm height
manish, 18 has 110 cm height

So, even though the primary constructor values are copied, the values in the class body like height can be changed separately.

Using equals() and hashCode()

**Declaration of hashCode() :

open fun **hashCode(): Int

**Properties of hashCode()

fun main() { val man1 = Person("manish", 18) val man2 = Person("rahul", 18) val man3 = Person("manish", 18)

println(man1.hashCode())
println(man2.hashCode())
println(man3.hashCode())

println("man1 == man2: ${man1 == man2}")
println("man1 == man3: ${man1 == man3}")

}

`

**Output:

835510190
-938448478
835510190
man1 == man2: false
man1 == man3: true

**Explanation:

man1 and man2 have same object contents, so they are equal, thus they have same hash code values.