thecodex.expert · The Codex Family of Knowledge
Kotlin

Delegation

Implementing an interface by forwarding every single method to another object used to mean writing that forwarding code by hand — Kotlin’s by keyword generates all of it automatically, in one word.

Kotlin 2.1 by for classes AND properties Last verified:
Canonical Definition

Class delegation (class Derived(b: Base) : Base by b) implements an interface by automatically forwarding every call to a held instance, without hand-writing the forwarding code for each method — genuine composition, made nearly as concise as inheritance. Property delegation (val x by lazy { ... }) hands a property's get/set logic to a separate delegate object; lazy computes and caches a value on first access (and only then), while observable notifies a callback whenever the property's value changes, both built into the standard library and commonly used without writing a custom delegate at all.

Class delegation: composition without the boilerplate

LoggingList automatically forwards every MutableList method to innerList via by — only add() is overridden with extra behavior; everything else (size, get, remove, and the rest of MutableList's full interface) just works, forwarded automatically.

Kotlinclass_delegation.kt
class LoggingList<T>(private val innerList: MutableList<T> = mutableListOf()) :
    MutableList<T> by innerList {   // forwards EVERY MutableList method to innerList automatically

    override fun add(element: T): Boolean {
        println("Adding: $element")
        return innerList.add(element)   // only this method has custom behavior
    }
}

val list = LoggingList<Int>()
list.add(5)          // prints "Adding: 5", then actually adds it
println(list.size)   // 1 — forwarded automatically, no code written for size at all

Property delegation: lazy initialization

The expensive computation inside lazy runs only the FIRST time expensiveValue is accessed — every subsequent access reuses the cached result, with zero extra code needed to implement that caching.

Kotlinlazy_delegation.kt
val expensiveValue: String by lazy {
    println("Computing...")   // runs only ONCE, on first access
    "the result"
}

println(expensiveValue)   // prints "Computing..." then "the result"
println(expensiveValue)   // prints only "the result" — cached, not recomputed

Property delegation: observable

The callback fires automatically on every reassignment, receiving both the old and new values — useful for reacting to a property's changes without manually wiring a listener pattern.

Kotlinobservable_delegation.kt
import kotlin.properties.Delegates

var name: String by Delegates.observable("initial") { _, old, new ->
    println("Changed from $old to $new")
}

name = "Alice"   // prints "Changed from initial to Alice"

Sources

1
JetBrains. Kotlin Documentation, "Delegation" and "Delegated properties," kotlinlang.org/docs/delegation.html.