lateinit vs lazy in Kotlin

lateinit vs lazy in Kotlin

Kotlin offers two ways to initialize properties lazily: lateinit and lazy. While both are used to delay initialization, they serve different use cases.


In this article, we’ll break down their differences, use cases, and real-world analogies to help you choose the right approach.


Join our upcoming 6 Weeks Android Mentorship Program

Complete Syllabus


1. Understanding lateinit

What is lateinit?

The lateinit keyword is used for mutable (var) properties that will be initialized later but before first use. It is primarily used with non-nullable types (except primitive types like Int, Double, etc.).

Syntax

class User {
    lateinit var name: String
    
    fun setUserName(userName: String) {
        name = userName
    }
    
    fun printName() {
        if (::name.isInitialized) {
            println("User name: $name")
        } else {
            println("Name is not initialized yet.")
        }
    }
}

fun main() {
    val user = User()
    user.setUserName("Akshay")
    user.printName()  // Output: User name: Akshay
}        


Real-World Analogy for lateinit

Think of lateinit as a hotel room booking system. When a guest books a room, the reservation is made, but the actual check-in happens later. The room is guaranteed to exist, but the guest hasn't occupied it yet.


When to Use lateinit?

  • When you must initialize a variable before first use, but not in the constructor.
  • When dependency injection frameworks like Hilt or Dagger are used.
  • When you need late property initialization in unit tests.


Advanced Insights on lateinit

✅ lateinit properties can be checked if they are initialized using ::property.isInitialized.

✅ lateinit cannot be used for val, as it is inherently mutable (var).

Hidden Pitfall: If lateinit property is never initialized and accessed, it results in a UninitializedPropertyAccessException.

Alternative: If lateinit is overused, consider using nullable types (String?) with !! assertions instead.


2. Understanding lazy

What is lazy?

The lazy keyword is used for read-only (val) properties and evaluates the assigned value only once, when accessed for the first time.

Syntax

class DatabaseConnection {
    val connection: String by lazy {
        println("Establishing Database Connection...")
        "Connected to Database"
    }
}

fun main() {
    val db = DatabaseConnection()
    println("Before accessing connection")
    println(db.connection)  // Output: Establishing Database Connection... Connected to Database
    println(db.connection)  // Output: Connected to Database (without re-evaluating)
}        


Real-World Analogy for lazy

Think of lazy as turning on a water heater. The heater remains off until someone actually needs hot water. The moment someone turns on the hot water tap, the heater starts, but once heated, it remains available for subsequent use without restarting.


When to Use lazy?

  • When a variable is expensive to compute (like database queries, API calls, or large object creations).
  • When you don't need the value immediately, but only when first accessed.
  • When ensuring thread safety in multi-threaded environments (lazy by default is thread-safe).


Advanced Insights on lazy

✅ The default lazy mode is thread-safe, meaning it synchronizes initialization across multiple threads.

✅ There are three lazy modes:

  • LazyThreadSafetyMode.SYNCHRONIZED (default, ensures thread-safety)
  • LazyThreadSafetyMode.PUBLICATION (allows multiple initializations but ensures only one is retained)
  • LazyThreadSafetyMode.NONE (no synchronization, best for single-threaded scenarios)

Hidden Pitfall: lazy should not be used for variables that are frequently accessed and require fast retrieval. Since it adds an internal locking mechanism, excessive usage can cause performance overhead.


3. Key Differences: lateinit vs lazy

lateinit

Usage - Works with var (mutable)

Initialization - Must be initialized before first use

Primitive Support - Not allowed

Multi-threading - Not thread-safe

Common Use Cases - Dependency injection, Android views, unit testing


lazy

Usage - Works with val (immutable)

Initialization - Initialized only on first access

Primitive Support - Allowed

Multi-threading - Thread-safe by default

Common Use Cases - Expensive object creation, Singleton patterns, thread safety


4. Which One Should You Use?

Choose lateinit if:

✅ You have a mutable property (var).

✅ You will guarantee initialization before first use.

✅ You’re using dependency injection or Android views.


Choose lazy if:

✅ You have an immutable property (val).

✅ You want to delay computation until first access.

✅ You’re dealing with expensive operations like database connections.


5. Conclusion

Both lateinit and lazy serve different purposes in Kotlin. While lateinit is useful for delaying initialization when you know it will be initialized before use, lazy ensures that a property is initialized only when required, making it ideal for expensive computations.

Understanding their differences will help you write efficient, optimized, and cleaner Kotlin code.


🔥 Senior Engineer's Take

  • Overuse of lateinit can lead to runtime crashes; always check ::property.isInitialized.
  • lazy properties should be used carefully in performance-critical applications.
  • If lateinit and lazy both seem like options, prefer lazy as it avoids mutable state.


🚀 Do you use lateinit or lazy in your projects? Let me know your thoughts in the comments below!


Join our upcoming 6 Weeks Android Mentorship Program

Complete Syllabus


Akshay Nandwana

Founder AndroidEngineers

You can connect with me on:



Book 1:1 Session

Join our upcoming classes

Aditya Patanwar

Time Will Tell (Since 2023 ) || Native Android Developer || Kotlin || Jetpack Compose || Data Structures And Algorithms C++ || MERN Stack

3mo

Worth Reading!!

Akshay Nandwana 🇮🇳

Technical Consultant - Google • Helping Devs Land Jobs 🚀 • 114M+ Impression • Android Engineer & Mentor • Ex-GSoC Mentor & GDSC Lead • Ex-Zee5, Doubtnut • Kotlin, Jetpack Compose, CMP

3mo

To view or add a comment, sign in

More articles by Akshay Nandwana 🇮🇳

  • 🚀 Jetpack Compose Cohort: May 1

    🚀 Jetpack Compose Cohort: May 1

    I'm thrilled to announce our upcoming intensive 7-day workshop designed to give you a hands-on, project-based journey…

  • Creating Magical Shared Element Transitions with Jetpack Compose

    Creating Magical Shared Element Transitions with Jetpack Compose

    Hi Android enthusiasts! Have you ever admired the beautiful animations when navigating between screens in apps like…

    1 Comment
  • Infix Notation in Kotlin

    Infix Notation in Kotlin

    Kotlin provides many features that enhance the readability and expressiveness of code. One such feature is infix…

  • Mastering Coding Patterns in Kotlin

    Mastering Coding Patterns in Kotlin

    As an Android Kotlin developer, understanding coding patterns is essential for writing clean, efficient, and scalable…

    2 Comments
  • Analytics Logging System in NowInAndroid App

    Analytics Logging System in NowInAndroid App

    This blog will walk you through the step-by-step process of building a scalable and testable analytics logging…

    1 Comment
  • GSoC Orgs for Android Enthusiasts 🚀

    GSoC Orgs for Android Enthusiasts 🚀

    🚀 Looking to contribute to Android-related projects and be part of Google Summer of Code (GSoC)? Here’s a curated list…

    1 Comment
  • Difference Between const val and val in Kotlin

    Difference Between const val and val in Kotlin

    Kotlin provides two keywords, and , for defining constants. While both are used to declare immutable values, there are…

    1 Comment
  • Design Patterns in Android Development

    Design Patterns in Android Development

    Design patterns are proven solutions to common problems in software design. They help structure code, improve…

  • Mastering LRU Cache in Kotlin

    Mastering LRU Cache in Kotlin

    As a Senior Engineer, I’ve found that mastering algorithms isn’t just about memorizing their definitions but truly…

  • Android Engineer Interview Questions

    Android Engineer Interview Questions

    Kotlin Difference Between const val and val? Answer What is Data Class in Kotlin? What are the different Coroutine…

    3 Comments

Insights from the community

Others also viewed

Explore topics