코틀린에서 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(모드 이름){ ... }과 같이 사용하면 됩니다.
반응형
'Programming' 카테고리의 다른 글
[Kotlin] 29. 컴패니언 객체 (0) | 2019.09.01 |
---|---|
[Kotlin] 28. 위임(Delegation) (0) | 2019.09.01 |
[Kotlin] 26. 지연초기화: lateinit (0) | 2019.08.27 |
[Kotlin] 25. Custom Getter & Setter (0) | 2019.08.27 |
[Kotlin] 24. 클래스 혹은 객체간의 관계 (0) | 2019.08.27 |