Kotlin Tutorial · Advanced Kotlin · Lesson 25 of 31
Kotlin Delegation: by lazy and Delegated Properties
Delegate interface implementations with by, and properties with lazy, observable and map-backed delegates.
Class delegation
class X(inner: Interface) : Interface by inner forwards every interface method to inner; you override only
what you want to change. It's composition without boilerplate.
interface Repository {
fun find(id: Int): String?
fun count(): Int
}
class MemoryRepository : Repository {
private val data = mapOf(1 to "Ana", 2 to "Ben")
override fun find(id: Int) = data[id]
override fun count() = data.size
}
class LoggingRepository(private val inner: Repository) : Repository by inner {
override fun find(id: Int): String? {
println("find($id)")
return inner.find(id)
}
}
fun main() {
val repo = LoggingRepository(MemoryRepository())
println(repo.find(2))
println(repo.count()) // forwarded without logging
}
Output
find(2) Ben 2
Run this on your computer — see “Get Started” for setup.
Delegated properties
by lazy { }computes the value on first access and caches it (thread-safe by default).Delegates.observableruns a callback on every change.- A property can be read from a
Map(val name: String by map).
import kotlin.properties.Delegates
class Settings(values: Map<String, Any?>) {
val theme: String by values
val fontSize: Int by values
val expensive: String by lazy {
println("computing...")
"ready"
}
var status: String by Delegates.observable("idle") { _, old, new ->
println("status: $old -> $new")
}
}
fun main() {
val s = Settings(mapOf("theme" to "dark", "fontSize" to 14))
println("${s.theme} ${s.fontSize}")
println(s.expensive)
println(s.expensive) // cached: no second "computing..."
s.status = "saving"
s.status = "saved"
}
Output
dark 14 computing... ready ready status: idle -> saving status: saving -> saved
Run this on your computer — see “Get Started” for setup.
Test yourself
When is a by lazy property's initializer run?
When the object is createdOn first access, and the result is cachedEvery time it's readAt compile time
Show answer
Answer: On first access, and the result is cached