References: Do it! 코틀린 프로그래밍

코틀린에서 lazy을 이용한 지연 초기화에 대해 알아봅니다.

 

 

1. lazy

 

앞서 알아본 lateinit는 val을 허용하지 않습니다.

var은 언제든 값이 변경될 수 있다는 문제를 갖고 있습니다.

lazy를 사용하면 val로 선언해도 지연 초기화를 사용할 수 있습니다.

 

lazy는 다음과 같은 특징을 갖습니다.

  • val에서만 사용 가능하다.
  • 호출 시점에 by laze {...} 정의에 의해 초기화를 진행한다.
  • 람다식으로 구성되어 lazy인스턴스 반환 값을 갖는 함수다.

 

 

2. lazy를 통한 프로퍼티 지연 초기화

 

다음 예시를 통해 lazy를 통해 프로파티를 지연 초기화시키는 방법에 대해 알아봅시다.

 

class LazyTest{
    init{ println("Init block") }
    val subject by lazy {
        println("Initialized by lazy.")
        "Kotlin programming"
    }
    fun flow(){
        println("Not initialized")
        println("Subject one: $subject")
        println("Subject two: $subject")
    }
}
fun main() {
    val lazyTest = LazyTest()
    lazyTest.flow()
}

 

  • val subject by lazy { : by lazy를 통한 지연 초기화. 프로퍼티에 최초 접근될 때 블록 내부의 내용이 실행된다.
  • println("Subject one: $subject") : 프로퍼티에 최초 접근하는 코드. 이때 by lazy 블록의 코드가 실행된다.
  • println("Subject two: $subject") : 프로퍼티가 이미 초기화되어 by lazy 블록의 코드가 실행되지 않는다.

위의 코드를 실행하면 다음과 같은 결과를 확인할 수 있습니다.

 

 

 

3. lazy를 통한 객체 지연 초기화

 

다음 예시를 통해 lazy를 통해 객체를 지연 초기화시키는 방법에 대해 알아봅시다.

 

class Person(val name: String, val aget: Int)
fun main() {
    var isPersonInitialized: Boolean = false
    val person: Person by lazy{
        isPersonInitialized = true
        Person("smoh", 28)
    }
    val personDelegate = lazy{ Person("smoh", 28) }
    println("person Init: $isPersonInitialized")
    println("personDelegate Init: ${personDelegate.isInitialized()}")
    println("person.name: ${person.name}")
    println("personDelegate.value.name = ${personDelegate.value.name}")
    println("person Init: $isPersonInitialized")
    println("personDelegate Init: ${personDelegate.isInitialized()}")
}

 

  • by lazy: by lazy를 사용한 객체의 지연 초기화. 
  • lazy{ Person("smoh", 28) : 위임 변수를 사용한 객체의 초기화
  • ${person.name} : 객체 내 프로퍼티에 접근할 때 지연 초기화가 이루어집니다.
  • ${personDelegate.value.name} : 객체 내 프로퍼티에 접근할 때 지연 초기화가 이루어집니다.

 

 

4. lazy의 모드들

 

lazy에는 SYNCRONIZED, PUBLICATION, NONE의 세 가지 모드가 있습니다.

 

  • SYNCRONIZED : lock을 사용해 단일 스레드만 사용하는 걸 보장합니다. 기본값입니다.
  • PUBLICATION : 여러 군데에서 호출될 수 있으나 처음 초기화된 후 반환 값을 사용합니다.
  • NON : lock을 사용하지 않아 빠르지만 여러 스레드가 접근할 수 있어 값의 일관성을 보장할 수 없습니다.

다른 모드를 사용하고 싶으면 by lazy(모드 이름){ ... }과 같이 사용하면 됩니다.

 

 

 

 

반응형

+ Recent posts