What is the difference between a `val` and a `var` property in Kotlin, and what does the compiler generate for each?
answer
- val = getter only, var = getter + setter
- val freezes the reference, not the object
- Val cannot be reassigned (compile error)
- Java sees getX()/setX()
- one assignment allowed for val
basics
~10 sA val is read-only — you set it once and can't reassign it. A var can be reassigned. The compiler creates a getter for both, and a setter only for var.
solid answer
~40 sA property declared with `val` is read-only: it generates a backing field and a public getter, but no setter, so you cannot reassign it after initialization. A `var` is mutable: it generates a backing field, a getter, and a setter. `val` means the reference is fixed, not that the referenced object is immutable — a `val list = mutableListOf(...)` can still have elements added. Reassignment of a `val` is a compile error (`Val cannot be reassigned`). For class properties, Kotlin synthesizes the accessors; from Java you call `getX()`/`setX()`. A `val` can also be backed by a custom getter computed on each access instead of a stored field.
code
kotlin · 7 linesclass Counter {
val createdAt = System.currentTimeMillis() // read-only
var count = 0 // mutable
fun inc() { count++ } // OK: var has a setter
// fun reset() { createdAt = 0L } // error: Val cannot be reassigned
}go deeper
Knows val is read-only and var is mutable, and that reassigning a val fails to compile.
Explains accessor synthesis (getter for val, getter+setter for var) and shallow immutability of val.
Discusses Java interop method names, when val is computed via a custom getter vs a stored field, and immutability design.
Frames val/var choice as an API-design and concurrency decision (immutable references aid thread-safety) across module boundaries.
## What is a property? In Kotlin a **property** is a class member that combines a (possibly hidden) **field** with **accessors** (a getter, and for mutable properties a setter). You never declare a raw Java-style field directly; you declare a property and the compiler synthesizes the accessors. ## `val` vs `var` - **`val`** (value) — *read-only*. Exactly one assignment is allowed (at declaration, in an `init` block, or in the constructor). The compiler generates a **getter only**. Reassigning later is a compile error: `Val cannot be reassigned`. - **`var`** (variable) — *mutable*. The compiler generates a **getter and a setter**, so it can be reassigned any number of times. ```kotlin class User(val id: Long, var name: String) val u = User(1, "Ana") u.name = "Bob" // OK — var has a setter // u.id = 2 // compile error — val has no setter ``` ## What the compiler generates For a simple property the compiler creates: - a private **backing field** (referenced inside accessors via the keyword `field`), - a `getX()` method, - a `setX()` method **only for `var`**. These are the methods Java code sees (`user.getId()`, `user.setName("Bob")`). ## `val` is shallow immutability `val` freezes the *reference*, not the object it points to: ```kotlin val items = mutableListOf(1, 2) items.add(3) // OK — the list object is mutable // items = mutableListOf() // error — can't rebind the val ``` For a deeply immutable collection use a read-only type like `List` plus `val`. ## Local vs member Both keywords work for **local variables** and **class properties**. Local `val`/`var` are just stack variables with no accessors; member properties get synthesized accessors as described above.
- Does `val` make the referenced object immutable?No. It only prevents reassigning the reference. A `val` holding a MutableList can still be mutated via add/remove.
- Can a `val` be initialized somewhere other than the declaration line?Yes — in the primary constructor parameter, an init block, or a secondary constructor, as long as it's assigned exactly once on every path before use.
A val is a name tag stuck to a box: you can change what's inside the box, but you can't move the tag to a different box.
saying these in an interview costs you the question
- Saying `val` makes the object deeply immutable
- Claiming `val` generates no getter
- Thinking `var` has no backing field
- Confusing `val` with Java `final` on a collection's contents