CodeBlanks Logo Icon CodeBlanks

Delegated properties

Learn delegation with by lazy and by observable.

Delegated properties

You can delegate the get/set behavior of a property to another object. by lazy computes a property on first access and caches it. Example: val config by lazy { loadConfig() }. On first access loadConfig() runs; later accesses return the cached value.

by Delegates.observable runs a lambda whenever a value is assigned. Example: var count by Delegates.observable(0) { _, old, new -> println("$old -> $new") }. On each assignment the old and new values reach the lambda. This is useful for change tracking and logging.

by lazy and observable details

by lazy is thread-safe by default; under concurrent first access the computation runs only once. You can change this with LazyThreadSafetyMode.

observable calls the lambda on every assignment; the assignment always happens. If you want to reject an assignment based on a condition, use vetoable; you will see it in the next lesson. observable suits side effects like logging, counting and cache invalidation.

Practice Apply by lazy and observable

Add import kotlin.properties.Delegates. Define val config by lazy { "Production" }. Define var counter by Delegates.observable(0) { _, old, new -> println("$old -> $new") }. In main call println(config), then assign counter = 1 and counter = 2.

Starter code

Main.kt
import kotlin.properties.Delegates

// Define config with the lazy delegate
// Define counter with the observable delegate

fun main() {
    // Print config, change counter twice
}

Sample solution

Main.kt
import kotlin.properties.Delegates

val config by lazy { "Production" }
var counter by Delegates.observable(0) { _, old, new -> println("$old -> $new") }

fun main() {
    println(config)
    counter = 1
    counter = 2
}

Expected output

Production
0 -> 1
1 -> 2

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Complete the by lazy declaration

Question
val config ____ lazy { loadConfig() }
Answer
val config by lazy { loadConfig() }

Explanation: by lazy computes on first access.

2 Match the delegated properties

Term Meaning
by lazy Lazy compute
by observable Change tracking
lazy { } On first access
observable { } On every set

3 When does by lazy compute?

  • At compile time
  • When the class loads
  • On first access Correct answer
  • Never

Explanation: by lazy computes on first access and caches the result.

All lessons in Intermediate