Exactly which properties of a data class get a generated componentN(), and what gotchas does that create for destructuring?
answer
- Only primary-constructor properties get componentN()
- Body properties are excluded
- Reordering ctor props silently breaks destructuring
- Order is part of the public contract
- Pair/Triple are data classes too
basics
~10 sOnly the properties listed in the data class's main constructor get componentN() functions, in the order they're written. Properties declared inside the class body don't get one, so you can't destructure them.
solid answer
~40 sA `data class` auto-generates `componentN()` only for properties declared in its **primary constructor**, numbered in declaration order. Properties declared in the **class body** are excluded — they get no `componentN()` and can't be reached by destructuring. The big gotcha is **positional fragility**: if you reorder constructor properties, every `val (a, b) = obj` call site silently rebinds to different values with no compile error (as long as the types still fit). Likewise, adding a new property in the middle shifts all later components. This is why destructuring large data classes is discouraged. Inheriting components isn't a concern since data classes can't be open. Note `Pair` and `Triple` are data classes too, hence `val (k, v) = pair`.
code
kotlin · 10 linesdata class Account(val id: Long, val owner: String) {
var balance: Long = 0 // body property: no component3()
}
fun main() {
val acc = Account(1, "Ada").apply { balance = 500 }
val (id, owner) = acc // fine
// val (id2, owner2, bal) = acc // won't compile: no component3()
println("$id $owner")
}go deeper
Knows data classes can be destructured but not the constructor-only rule.
States that only primary-constructor properties get components, in order, and body properties don't.
Articulates positional fragility on reorder and treats component order as a public contract.
Sets team policy: limit destructuring to small stable types and forbid reordering of destructured DTOs.
## What gets generated For a `data class`, the compiler generates `componentN()` **only** for **primary-constructor properties**, in their declaration order: ```kotlin data class User(val id: Long, val name: String) { var lastLogin: Instant? = null // body property — NO componentN() } val (id, name) = user // OK // val (id, name, login) = user // compile error: no component3() ``` ## Constructor params that aren't properties A primary-constructor parameter written **without** `val`/`var` is not a property and gets no `componentN()`: ```kotlin data class P(val x: Int, y: Int) // y has no component2() ``` (Actually a plain ctor param in a data class is a compile error unless it's val/var, so in practice all data-class ctor params are properties — but the rule "only properties get components" is the principle.) ## Gotcha 1: positional fragility on reorder Because binding is positional, reordering constructor properties silently changes what every destructuring site receives: ```kotlin // v1 data class Geo(val lat: Double, val lng: Double) val (lat, lng) = geo // v2 — someone reorders to (lng, lat); call site STILL compiles // now `lat` holds longitude. Silent bug. ``` No error fires because both are `Double`. This is the single biggest destructuring hazard. ## Gotcha 2: inserting a property mid-list Adding a property between existing ones shifts all later components, breaking call sites that destructured beyond it (by position) — sometimes with a compile error, sometimes silently if types align. ## Gotcha 3: body vs constructor Moving a property into the class body to compute it removes its component, breaking existing `val (...)` destructurings. ## Practical guidance - Prefer destructuring small, stable, semantically-ordered types (coordinates, key/value). - For wide DTOs, prefer named property access; reordering then can't silently corrupt data. - `Pair`/`Triple` work because they are themselves data classes with component1()/2()/3(). ## Mitigation Treat the component order as part of the public contract. If consumers destructure, document the order and avoid reordering; binary/source compatibility for destructuring depends on it.
- Can you destructure a property declared in the data class body?No. Only primary-constructor properties get componentN(); body properties are excluded and cause a compile error if you try to reach them.
- Why is reordering data-class constructor properties dangerous?Destructuring binds by position. Reordering silently rebinds call sites to different values, with no error when the types still match.
saying these in an interview costs you the question
- Claiming body properties also get componentN()
- Saying reordering is safe because it's a data class
- Not recognizing component order as a compatibility contract
- Thinking component count equals total property count