먼저 lateinit 과 lazy에 대한 일반적인 설명은 다음과 같습니다.
개념 설명
- lateinit
- "lateinit"은 "late initialization"의 약어로, Kotlin에서 사용되는 키워드입니다.
- 일반적으로 Kotlin에서 변수를 선언하면 해당 변수는 초기값을 가져야 합니다. 그러나 종종 변수를 선언한 후에 초기화해야 하는 경우가 있습니다. 이때 "lateinit"을 사용할 수 있습니다.
- "lateinit"은 변수를 선언할 때 초기값을 할당하지 않고, 나중에 코드의 어느 지점에서 직접 초기화해야 합니다. 이를 통해 초기화 지연을 허용하면서 컴파일러에게 변수가 나중에 초기화될 것임을 알릴 수 있습니다.
- 다음은 "lateinit" 변수를 선언하는 예시입니다:
kotlinCopy code
lateinit var myVariable: String
fun initializeVariable() {
myVariable = "Initialized"
}
- lazy
- "lazy"는 Kotlin의 표준 라이브러리 함수 중 하나입니다.
- "lazy" 함수는 변수를 처음으로 액세스할 때까지 초기화를 지연시키는 데 사용됩니다. 이는 변수가 필요한 시점에만 초기화되며, 초기화 비용이 높거나 필요한 경우에만 초기화해야 하는 상황에 유용합니다.
- "lazy" 함수를 사용하려면 초기화 코드를 람다 함수로 감싸서 전달하고, 변수를 사용할 때 해당 람다 함수가 호출됩니다. 이후에는 해당 변수에 저장된 값을 재사용하게 됩니다.
- 다음은 "lazy"를 사용하여 변수를 초기화하는 예시입니다:
kotlinCopy code
val myLazyVariable: String by lazy {
println("Initializing myLazyVariable")
"Initialized"
}
fun main() {
println("Before accessing myLazyVariable")
println(myLazyVariable)
println("After accessing myLazyVariable")
}
차이점
- 초기화 시점:
- lateinit
"lateinit" 변수는 나중에 직접 초기화해야 합니다. 초기화는 변수를 선언한 후 언제든지 발생할 수 있으며, 사용자가 초기화 시점을 제어할 수 있습니다.
- lazy
"lazy" 변수는 처음으로 액세스될 때 초기화됩니다. 이전에는 초기화가 지연되며 변수가 필요한 시점에 초기화됩니다.
- 초기화 여부
- lateinit
lateinit 변수를 초기화하지 않은 상태에서 사용하려고 시도하면 예외가 발생합니다. 초기화 여부를 체크해야 합니다.
- lazy
lazy 변수는 필요한 시점에 자동으로 초기화되므로 초기화 여부를 별도로 확인할 필요가 없습니다.
- 초기화 방법
- lateinit
초기화 코드를 변수를 선언한 후에 별도로 작성해야 합니다.
- lazy
초기화 코드는 변수를 선언할 때 람다 함수로 전달됩니다.
- nullable 타입 사용 여부
- lateinit
일반적으로 nullable이 아닌(non-nullable) 변수에서만 사용할 수 있습니다. 따라서 초기화되지 않은 lateinit 변수를 사용하려고 시도하면 컴파일 시간 에러가 발생합니다.
예를 들어, lateinit var myVariable: String와 같이 nullable하지 않은 문자열 변수에 사용됩니다.
- lazy
"lazy"는 nullable 또는 non-nullable 변수 모두에 사용할 수 있습니다. 변수 타입에는 엄격한 제한이 없으며, 초기화 람다의 반환 타입과 변수 타입이 일치하면 됩니다.
예를 들어, val myLazyVariable: String? by lazy { "Initialized" }와 같이 nullable 문자열 변수에 사용할 수 있습니다. 또한, val myLazyVariable: Int by lazy { 42 }와 같이 non-nullable 정수 변수에도 사용할 수 있습니다.
- 기본(Primitive) 데이터 형식 사용 여부
- lateinit
기본 데이터 형식 변수에는 "lateinit"를 적용할 수 없습니다. 즉, "lateinit"은 정수, 부동 소수점, 문자, 불린 등과 같은 기본 데이터 형식 변수에 사용할 수 없습니다.
예를 들어, lateinit var myString: String과 같이 문자열 변수에 사용할 수 있지만, lateinit var myInt: Int와 같이 정수 변수에는 사용할 수 없습니다.
"lateinit"은 주로 객체(클래스) 형식 변수의 초기화를 지연시키는 데 사용됩니다
- lazy
"lazy"는 기본 데이터 형식 변수에도 사용 가능합니다. 하지만 "lazy" 변수가 기본 데이터 형식을 저장하려면 해당 데이터 형식을 래퍼 클래스(예: Int)로 선언해야 합니다.
예를 들어, *val myLazyInt: Int by lazy { 42 }*와 같이 "lazy"를 사용하여 정수(기본 데이터 형식) 변수를 초기화하려면 기본 데이터 형식을 래퍼 클래스(Int)로 선언해야 합니다.
하지만 기본 데이터 변수를 지연 초기화 하는 경우는 거의 없습니다. lazy의 목적이 생성비용이 큰 객체의 지연 초기화 이므로, 기본 데이터 변수를 지연초기화 하는 것은 lazy의 사용 목적을 벗어났다고 볼 수 있습니다.
- val 과 var 사용 여부
- lateinit
"lateinit" 변수는 var로 선언해야 합니다. 즉, 변수의 값은 초기화 이후에 변경될 수 있습니다.
- lazy
"lazy" 변수는 val로만 선언해야 합니다. "lazy"는 변수를 처음 액세스할 때 한 번 초기화되고 그 이후에는 값을 변경할 수 없도록 설계된 메커니즘입니다. 따라서 "lazy" 변수는 val로 선언해야 합니다.
- 사용 사례
- lateinit
주로 DI (의존성 주입) 프레임워크에서 빈(bean)을 나중에 초기화해야 할 때 또는 Android 개발에서 View 요소 초기화 등과 같이 초기화를 나중에 수행해야 하는 경우에 사용됩니다.
- lazy
주로 초기화 비용이 높은 작업을 수행하는 변수나 여러 번 사용하지 않는 경우, 변수를 처음 액세스할 때 초기화해야 하는 경우에 사용됩니다.