Delegated properties
- Kotlin course
- Intermediate
- Lesson 71/116
- 5 min
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
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
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
val config ____ lazy { loadConfig() }
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.