lateinit and Lazy Initialization

Why lateinit?

Non-null properties must be initialised when the object is created. Sometimes the value arrives later - for example in Android, views and injected dependencies are set in onCreate(), not in the constructor. lateinit var promises the compiler that you will set the value before using it.

  • Only for var (not val).
  • Only for non-null, non-primitive types (String, your classes - not Int, Boolean).
  • Reading it before assignment throws UninitializedPropertyAccessException.
  • Check with this::prop.isInitialized.

lateinit in Action

Example

class ProfileScreen {
    lateinit var userName: String

    fun onCreate() {
        userName = "Sneha"   // set later, e.g. after loading data
    }

    fun render() {
        if (this::userName.isInitialized) println("Hello, $userName")
        else println("Still loading...")
    }
}

fun main() {
    val screen = ProfileScreen()
    screen.render()
    screen.onCreate()
    screen.render()
}

Output

Still loading...
Hello, Sneha

Forgetting to Initialise

Example

Accessing a lateinit property too early crashes the program.

class Repo {
    lateinit var baseUrl: String
}

fun main() {
    val repo = Repo()
    println("Calling " + repo.baseUrl)
}

Output

Exception: kotlin.UninitializedPropertyAccessException: lateinit property baseUrl has not been initialized

by lazy

For a val that is expensive to create, use by lazy { }: the block runs only on first access and the result is cached. Delegation is covered in depth at the advanced level.

Example

class AppConfig {
    val settings: Map<String, String> by lazy {
        println("Loading settings...")
        mapOf("theme" to "dark", "lang" to "en")
    }
}

fun main() {
    val config = AppConfig()
    println("Config object created")
    println(config.settings["theme"])
    println(config.settings["lang"])  // no second "Loading"
}

Output

Config object created
Loading settings...
dark
en
lateinit varval ... by lazy
Mutable?yes (var)no (val)
Who sets the valueyou, laterthe lambda, on first read
Primitive typesnot allowedallowed
Typical useAndroid views, DI fields, test setupexpensive objects, caches