lazy

Compute on First Use

val x by lazy { ... } runs the block the first time x is read and caches the result. Good for expensive objects that might not be needed (a database, a big regex, a formatter).

Example

class ReportScreen {
    val heavyChart: String by lazy {
        println("  building chart (expensive)...")
        "Bar chart with 12 months"
    }
}

fun main() {
    val screen = ReportScreen()
    println("Screen created")
    println("1st read: ${screen.heavyChart}")
    println("2nd read: ${screen.heavyChart}")
}

Output

Screen created
  building chart (expensive)...
1st read: Bar chart with 12 months
2nd read: Bar chart with 12 months

Thread-safety Modes

ModeBehaviour
lazy { } = SYNCHRONIZEDdefault; a lock makes sure the block runs once, even with many threads
lazy(LazyThreadSafetyMode.PUBLICATION) { }several threads may run the block, first result wins
lazy(LazyThreadSafetyMode.NONE) { }no locking; fastest; only for single-thread use (e.g. Android UI)
lazylateinit
Works withvalvar
Initialised bythe lambda, on first readyou, any time later
Typesanynon-null, non-primitive
Typical useexpensive computed valuesdependency injection, views set in onCreate