skip to content

What does the generated copy() function on a Kotlin data class do, and why is it useful for immutable data?

level: juniorimportance: must knowfreq 80%

answer

  1. Compiler-generated for data classes
  2. Params mirror primary constructor, default to current value
  3. Non-destructive update of val properties
  4. Shallow copy — references shared
  5. Original stays unchanged

basics

~10 s

copy() makes a new object that is the same as the old one, except for the properties you choose to change. The original stays untouched, so you update data without modifying it in place.

solid answer

~40 s

For every data class, the Kotlin compiler generates a copy() function whose parameters mirror the primary-constructor properties, each defaulting to the current instance's value. Calling copy(name = "X") returns a brand-new instance with name replaced and all other properties copied across unchanged. Because data classes typically declare val properties, you cannot mutate state in place; copy() is the idiomatic non-destructive update. It only covers properties declared in the primary constructor, performs a shallow copy (referenced objects are shared, not duplicated), and pairs naturally with immutable design: keep objects read-only and produce new versions for each state transition. This makes state changes explicit, thread-friendlier, and easy to reason about.

code

kotlin · 6 lines
kotlin
data class User(val name: String, val age: Int)

val u1 = User("Ada", 30)
val u2 = u1.copy(age = 31)
println(u1) // User(name=Ada, age=30)
println(u2) // User(name=Ada, age=31)

go deeper

for a junior

Knows copy() returns a new object changing only named properties and leaves the original intact.

for a middle

Adds that defaults come from the current instance and only primary-constructor props are covered.

for a senior

Frames copy() as the idiomatic non-destructive update for val-based immutable design and notes shallow-copy semantics.

for a principal

Positions copy() within an immutability strategy and its limits at scale (shallow copy, nested updates, boilerplate).

## What copy() is A **data class** in Kotlin is a class declared with the `data` keyword whose main job is to hold data. For such a class the compiler auto-generates several members, one of which is `copy()`. `copy()` lets you create a **new instance** based on an existing one, changing only the properties you specify and keeping the rest identical. ## Why it exists Data classes usually declare their properties as `val` (read-only). A `val` cannot be reassigned after construction, so you cannot do `user.name = "new"`. Instead of mutating, you create a *new* object — this is a **non-destructive update**. `copy()` makes that ergonomic. ## How the signature is generated For each property in the **primary constructor**, `copy()` gets a parameter with the **same name** and a **default value equal to the current instance's value**. So you only pass the ones you want to change. ```kotlin data class User(val name: String, val age: Int) val u1 = User("Ada", 30) val u2 = u1.copy(age = 31) // User(name=Ada, age=31) // u1 is unchanged: User(name=Ada, age=30) ``` ## Key facts - **Only primary-constructor properties** participate. Properties declared in the class body are NOT copied via parameters. - It is a **shallow copy**: if a property holds a reference (e.g., a `List` or another object), the new instance shares that same reference; the referenced object is not duplicated. - The original instance is never modified. - Use **named arguments** (`copy(age = 31)`) for clarity, since positional copies are error-prone. ## Typical use ```kotlin fun birthday(user: User): User = user.copy(age = user.age + 1) ``` This returns a new `User`, leaving the input untouched — the foundation of immutable state handling.

  • Does copy() modify the original object?
    No. It returns a new instance; the original is left exactly as it was.
  • What value do copy() parameters default to?
    Each parameter defaults to the corresponding property's value on the instance you call copy() on.

Like photocopying a form and editing one field on the copy — the original sheet is untouched.

saying these in an interview costs you the question

  • Saying copy() mutates the original in place
  • Claiming it deep-copies nested objects
  • Thinking it copies properties declared in the class body
  • Believing copy() is available on every class, not just data classes

context