CodeBlanks Logo Icon CodeBlanks

lateinit and lazy

Learn deferred initialization with lateinit and by lazy.

lateinit

lateinit works only for var properties of non-null reference types. It tells the compiler you will initialize the property later, not at declaration. This is handy when dependencies are wired during a setup phase.

Example: lateinit var service: UserService. Here service is not initialized at declaration; later service = RealService() assigns it. Reading it before assignment throws an UninitializedPropertyAccessException. It cannot be used with primitive types or val properties.

by lazy

by lazy computes a val property on first access and caches the result. This is the standard way to do lazy initialization; the computation runs only once.

Example: val config: String by lazy { loadConfig() }. On first read of config, loadConfig() runs and the result is stored. Subsequent reads return the same value. This is used to run expensive work only when needed. It is thread-safe by default.

Practice Define the Config class

Define a class named Config. Add a lateinit var apiKey: String property. Add a val cachedConfig: String by lazy { "settings loaded" } property. In main create a Config instance, assign "secret123" to apiKey and print both properties with println.

Starter code

Main.kt
// Define the Config class
// apiKey property with lateinit
// cachedConfig property with by lazy
// instantiate, assign apiKey, print both

Sample solution

Main.kt
class Config {
    lateinit var apiKey: String
    val cachedConfig: String by lazy {
        "settings loaded"
    }
}

fun main() {
    val c = Config()
    c.apiKey = "secret123"
    println(c.apiKey)
    println(c.cachedConfig)
}

Expected output

secret123
settings loaded

Questions and answers

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

1 Complete the lateinit definition

Question
class App {
    ____ var service: UserService
}
Answer
class App {
    lateinit var service: UserService
}

Explanation: lateinit var declares a property initialized later.

2 Match lateinit and lazy concepts

Term Meaning
lateinit var Late-assigned var
by lazy val computed on first access
val by lazy Read-only lazy property
UninitializedPropertyAccessException Early access error

3 Which is a valid by lazy definition?

  • val config: String by lazy { load() } Correct answer
  • var config by lazy { load() }
  • lateinit val config: String
  • val config = lazy

Explanation: by lazy is used with a val for a read-only property.

All lessons in Intermediate