skip to content

Properties & Backing Fields

A Kotlin property is a getter and possibly a setter; the backing field only exists when an accessor references field. Interviewers ask because knowing when no field is generated explains both computed properties and interface properties.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

What is the difference between a `val` and a `var` property in Kotlin, and what does the compiler generate for each?

level: juniorimportance: must knowfreq 85%

answer

  1. val = getter only, var = getter + setter
  2. val freezes the reference, not the object
  3. Val cannot be reassigned (compile error)
  4. Java sees getX()/setX()
  5. one assignment allowed for val

basics

~10 s

A 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 s

A 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 lines
kotlin
class 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

for a junior

Knows val is read-only and var is mutable, and that reassigning a val fails to compile.

for a middle

Explains accessor synthesis (getter for val, getter+setter for var) and shallow immutability of val.

for a senior

Discusses Java interop method names, when val is computed via a custom getter vs a stored field, and immutability design.

for a principal

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

context

open as a page

What is the `field` keyword, and inside which scope is it available?

level: middleimportance: must knowfreq 75%

basics

~10 s

field refers to the property's hidden storage slot. You can only use it inside that property's getter or setter. It lets you read or write the stored value without calling the accessor again.

open as a page

What is `lateinit var`, what are its restrictions, and how do you safely check whether it has been initialized?

level: seniorimportance: must knowfreq 70%

basics

~10 s

lateinit var lets you declare a non-null property without setting it right away, promising to assign it before first use. Reading it too early throws an exception. You can check readiness with this::prop.isInitialized.

open as a page

Under exactly what conditions does the Kotlin compiler NOT generate a backing field for a property?

level: middleimportance: should knowfreq 60%

basics

~10 s

If the property's getter (and setter for a var) are fully custom and never use the field keyword, there's no stored value, so the compiler skips the backing field. The value is computed instead.

open as a page

Explain property initialization order and how Kotlin properties surface to Java callers (including the `@JvmField` escape hatch).

level: seniorimportance: should knowfreq 45%

basics

~20 s

Properties and init blocks run top to bottom in the order they appear, after the primary constructor's parameters are set. From Java, Kotlin properties look like getX()/setX() methods unless you annotate the field with @JvmField to expose it directly.

open as a page