Kotlin

지연초기화

공부처음하는사람 2023. 12. 25. 00:52

lateinit / lazy

보통은 클래스에서 기본적으로 선언하는 프로퍼티는 null 값을 가질 수 없다.

그러므로 반드시 초기화가 되어야 하는것이 규칙인데, 초기화를 미룰 때 지연초기화 (lateinit, lazy)를 사용한다.

언제 사용할까?

의존성이 있는 초기화나 유닛 테스트를 위한 코드를 작성하면서, 설정에 의한 초기화를 할 때 불편하다.

Car클래스의 초기화 부분이 Engine클래스와 의존성을 가질 때, Engine 객체가 생성되지 않으면

완전하게 초기화 할 수 없다. 이처럼 특정 객체에 의존성이 있을 때 지연초기화를 해야한다.

 

lateinit 지연초기화 예시

class Person2 {
    lateinit var name: String //지연초기화 선언

    fun test() {
        if(!::name.isInitialized) {
            println("not initialized")
        } else {
            println("initialized")
        }
    }
}

fun main() {
    val kildong = Person2() // 객체를 생성해도 name은 초기화되지 않는다. 지연초기화를 허용했기에
    kildong.test()
    kildong.name = "kildong" // 이 시점에서 초기화됨 (지연초기화)
    kildong.test()
    println("name =${kildong.name}")

}

 

출력값은



not initialized
initialized
name = kildong



이 나오는데, 지연초기화가 언제 되는지 코드블록을 보고 생각해보자

lateinit은 var 에만 사용이 가능하다. val엔 사용이 불가능하다.

 

 

lazy 지연초기화 사용예시

class Person3(val name: String, val age: Int)

fun main() {
    var isPersonInstantiated: Boolean = false

    val person : Person3 by lazy {
        isPersonInstantiated = true
        Person3("kim", 23)
    }
    val personDelegate = lazy { Person3("hong", 40)}

    println("person Init: $isPersonInstantiated")
    println("personDelegate Init: ${personDelegate.isInitialized()}")

    println("person.name = ${person.name}") // 이 시점에서 초기화
    println("personDelegate.value.name = ${personDelegate.value.name}") // 이 시점에서 초기화

    println("person Init: $isPersonInstantiated")
    println("personDelegate Init: ${personDelegate.isInitialized()}")
}

 

출력값은



person Init: false
personDelegate Init: false
person.name = kim
personDelegate.value.name = hong
person Init: true
personDelegate Init: true


언제 지연초기화가 되었는지 확인해보자.

lazy는 val에만 사용가능하다.

* property에 최초로 접근한 시점에 해당 property가 초기화되는 것이 핵심이다.

'Kotlin' 카테고리의 다른 글

인터페이스  (1) 2023.12.25
추상클래스  (1) 2023.12.25
프로퍼티 (Getter / Setter)  (0) 2023.12.24
캡슐화  (0) 2023.12.24
다형성  (0) 2023.12.23