Kotlin 초기화 지연(lateinit, by lazy)


lateinit

클래스의 속성은 초기화가 필요하지만 lateinit를 이용하여 초기화를 지연시킬 수 있다.
Int 등의 원시적 타입에는 사용할 수 없고, Null 허용 타입에도 사용할 수 없다. var 변수 밖에 사용할 수 없는 등의 제한이 있다.

class Foo {
    lateinit var name: String        // init()를 호출하기 전까지 초기화 필요
    fun init(name: String) { this.name = name }
}

by lazy

lateinit과 비슷한 by lazy가 있다. Int이나 Null 허용 형식도 지정 가능 하지만, val 변수 밖에 사용할 수 없다.
선언 부에는 초기화를 위한 람다 식을 작성한다.
처음에 그 값이 필요하게 되었을 때 즉, 참조 되었을 시점에서 초기화 된 값이 참조되지 않은 경우 초기화가 된다.

아래 예제처럼 DB 연결 객체를 한번만 초기화 해야 하는 경우에 활용할 수 있다.

fun connectToDB() {
    ...
    return db
}
fun main() {
    val db by lazy { connectToDB() }
}

실제로 초기화가 한번만 되는지 간단한 예제를 작성해서 실행해 보자.

class ByLazy {
    val greeting: String by lazy {
        println("Greeting is Initialized!!!!") // 한번만 실행된다.
        "Hello"
    }
}

fun main() {
    val byLazy = ByLazy()
    println("Greeting is Not Initialized")
    println("Greeting one : ${byLazy.greeting}")
    println("Greeting two : ${byLazy.greeting}")
    println("Greeting three : ${byLazy.greeting}")
}

Output:

Greeting is Not Initialized
Greeting is Initialized!!!!
Greeting one : Hello
Greeting two : Hello
Greeting three : Hello

결과를 보면 처음 변수 greeting를 받아 올때 한번만 "Greeting is Initialized!!!!"가 표시되고 다음부터는 표시되지 않는 것을 볼 수 있다.