lateinit vs by lazy

Kotlin language Junior Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Predict the output

What does this print?

class Report {
    val total: Int by lazy {
        println("computing")
        42
    }
}

fun main() {
    val r = Report()
    println("created")
    println(r.total)
    println(r.total)
}
Options
Hint 1 of 1

When does a lazy block run, and how often?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A created, computing, 42, 42

Correct. lazy runs once, on first access, then returns the cached value.

Why not the others?
  • B computing, created, 42, 42. Nothing runs at construction.
  • C created, computing, 42, computing, 42. The value is cached after the first read.
  • D created, 42, 42. The lambda's println runs on first access.

30-second answer

lateinit var is for a non-null property that is set later by something else, like dependency injection or a test setup, before it's read. Reading it early throws UninitializedPropertyAccessException. val x by lazy { } computes the value on first access and caches it, thread-safely by default. Use lazy for expensive values you can compute yourself.

Practise saying it · 30 s. No recording, just a timer

Compare lateinit and lazy.

Say your answer out loud, then check which of these points you covered:

  • lateinit: set later by someone else
  • Throws if read early
  • lazy: computed once on first access
  • lazy is synchronized by default

Deep dive

lateinit can't be used with primitives or nullable types.

Check with ::prop.isInitialized inside the class.

lazy's default mode is synchronized; LazyThreadSafetyMode.NONE is faster on one thread.

A lazy that captures an Activity can leak it if the holder outlives the Activity.

Common mistakes

  • Using lateinit to dodge null safety and crashing on first read.
  • Using lazy for values that depend on later state.
  • Using lazy with an Activity in a long-lived object.

Senior take & follow-ups

Map each to who initialises it: someone else (lateinit) vs the property itself on first read (lazy).

Follow-up questions

Think of your answer first, then open the hint.

  1. Is lazy thread-safe?

    Show hint

    Yes by default (synchronized).

  2. Can lateinit hold an Int?

    Show hint

    No, only non-primitive, non-null types.

Suggest a fix if something here is wrong or out of date.