본문 바로가기

Kotlin

by lazy vs lateinit

728x90

1. by lazy 

 

public actual fun <T> lazy(initializer: () -> T): Lazy<T> = SynchronizedLazyImpl(initializer)

public actual fun <T> lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy<T> =
    when (mode) {
        LazyThreadSafetyMode.SYNCHRONIZED -> SynchronizedLazyImpl(initializer)
        LazyThreadSafetyMode.PUBLICATION -> SafePublicationLazyImpl(initializer)
        LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer)
    }
public enum class LazyThreadSafetyMode {
 
    /**
     * Locks are used to ensure that only a single thread can initialize the [Lazy] instance.
     */
    SYNCHRONIZED,
 
    /**
     * Initializer function can be called several times on concurrent access to uninitialized [Lazy] instance value,
     * but only the first returned value will be used as the value of [Lazy] instance.
     */
    PUBLICATION,
 
    /**
     * No locks are used to synchronize an access to the [Lazy] instance value; if the instance is accessed from multiple threads, its behavior is undefined.
     *
     * This mode should not be used unless the [Lazy] instance is guaranteed never to be initialized from more than one thread.
     */
    NONE,
}

lazy는 변수를 초기화 하는 ()-> T 함수 타입의 람다함수를 파라미터로 받는다. 

lazy로 선언한 변수를 getter를 호출하는 첫 쓰레드가 초기화 람다함수를 실행하고, 그 결과값을 가지고 있다가 다음 getter부터는 그 값을 리턴한다. 람다식을 호출할 때 다른 쓰레드가 들어오지 못하게 락을 걸어줘야하는데 세 가지 모드가 있다고 한다. default 모드는 SYNCHRONIZED다.

 

 

lazy를 정리하면 다음과 같다

 

  • by lazy는 계산식(람다 함수)을 한번만 호출되고 그 계산값을 기억한다.
  • 그러므로 val이고 값을 변화할수 없다.
  • 파라미터로 람다함수를 받는다.
  • 기본적으로 synchronized 모드로 동작하며 다른 모드로 바꿀수는 있다..

 

 

2. lateinit

 

코틀린에서 not-null type으로 지정된 프로퍼티는 반드시 생성자에서 초기화 해줘야한다.

하지만 DI를 통해서 의존성을 주입받거나 단위 테스트의 Setup단계에서는 생성자에서 이러한 초기화를 못하는 경우도 있다.

이럴 때를 대비해서 lateinit으로 선언을 할 경우 이 케이스를 피해줄 수 있다.

 

lateinit 키워드는 다음 특징을 가진다.

 

  • 반드시 var 타입으로 선언해줘야 하고 주 생성자에 있으면 안 되고 클래스 몸체에 선언되어 한다.
  • 그리고 커스텀 setter나 getter 또한 가지면 안된다.
  • Non-null 타입이여야 하고 원시타입에 대해서는 적용할 수 없다.
  • 반드시 초기화 후에 접근해야한다. 그러지 않으면 UninitializedPropertyAccessException이 발생한다.

stackoverflow.com/questions/36623177/kotlin-property-initialization-using-by-lazy-vs-lateinit

 

Kotlin - Property initialization using "by lazy" vs. "lateinit"

In Kotlin if you don't want to initialize a class property inside the constructor or in the top of the class body, you have basically these two options (from the language reference): Lazy Initiali...

stackoverflow.com

 

'Kotlin' 카테고리의 다른 글

Kotlin 익명 클래스  (0) 2021.08.21
시스템  (0) 2021.06.13
JVM 언어 의 공변  (0) 2021.02.22
코틀린 제네릭스  (0) 2021.02.19