Kotlin

Kotlin

Made by DeepSource

Found usages of lateinit modifier KT-W1047

Bug risk
Major

The lateinit modifier in Kotlin is used to indicate that a non-null property will be initialized later, usually before its first use. While lateinit can be convenient in certain situations, it also introduces some potential issues and risks, which is why it is generally considered bad practice or discouraged in Kotlin.

Here are some reasons why lateinit can be problematic:

1. Nullable safety: Kotlin is designed to promote null safety, and the type system encourages developers to
   explicitly handle nullable and non-nullable types. By using lateinit, you bypass this safety mechanism because
   the compiler allows you to declare a non-nullable property without initializing it immediately. If the property
   is accessed before it's initialized, a NullPointerException will occur at runtime, breaking the null safety
   guarantee of Kotlin.

2. Potential bugs and runtime crashes: Since lateinit properties are not checked at compile-time for initialization,
   it increases the likelihood of runtime crashes due to null pointer exceptions. It can be challenging to track down
   the cause of such crashes, especially in larger codebases.

3. Maintenance challenges: lateinit properties make code harder to reason about because their initialization is
   deferred. It becomes difficult to determine when and where a property is being initialized or reassigned, which
   can lead to bugs and make the codebase more challenging to maintain and debug.

4. Interoperability and platform limitations: lateinit is a Kotlin-specific feature and may not work well with
   certain frameworks, libraries, or platforms. It may cause compatibility issues when integrating with Java code
   or when targeting platforms other than the JVM, such as JavaScript or native.

Bad Practice

class Example {
    lateinit var name: String

    // Will be called in the future.
    fun initializeName() {
        name = "John Doe"
    }
}

Recommended

Use lazy initialization instead of lateinit.

class Example {
    val name: String by lazy {
        "John Doe"
    }

    fun printName() {
        println(name)
    }
}

References