Kotlin의 프로퍼티 위임과 초기화 지연은 어떻게 동작하는가?
프로퍼티에 대한 접근과 초기화는 객체지향 프로그래밍 언어에서는 친숙하고 중요하다.
Kotlin 역시 프로퍼티에 대한 여러가지 접근 방법을 제공하고 있으며, Lazy initialization(초기화 지연)을 적용할 수 있는 by lazy 가 좋은 사례이다.
** by lazy는 Kotlin에서 초기화 지연을 실행하는 읽기 전용의 프로퍼티를 구현할 때 사용한다.
이 글에서 Kotlin에서 Delegation을 이용하여 프로퍼티를 다루는 방법과 by lazy가 어떻게 동작하는지를 볼 수 있다.
** Delegated Property는 프로퍼티에 대한 getter/setter를 위임하여 위임받은 객체로 하여금 값을 읽고 쓸 때 어떤 중간 동작을 수행하는 기능이다.
** 다음과 같이 by <delegate> 형식으로 Delegated property를 선언할 수 있다.
val/var <property name>: <Type> by <delegate> |
** 프로퍼티를 위임받을 대상은 다음과 같은 형태로 정의할 수 있다.
class Delegate {
operator fun getValue(
thisRef: Any?,
property: KProperty<*>
): String {
// return value
}
operator fun setValue(
thisRef: Any?,
property: KProperty<*>, value: String
) {
// assign
}
} |
값에 대한 모든 읽기 동작은 위임된 대상의 getValue()을 호출하는 형태로 변경되며, 쓰기 동작의 경우 setValue()로 전달되는 구조이다.
1. Helper Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package com.javasampleapproach.lazyinit class BookManager { companion object { fun loadBooks(person: Person): List<String> { println("Load books for ${person.name}") return listOf("Master Kotlin at JavaSampleApproach", "Be Happy to become Kotlineer") } } } | cs |
2. Class with Delegated property
1 2 3 4 5 6 | package com.javasampleapproach.lazyinit data class Person(val name: String) { val books by lazy { BookManager.loadBooks(this) } } | cs |
** lazy를 통해 선언된 books 프로퍼티를 위임하는 것임을 알 수 있다.
** lazy()는 Kotlin 표준 라이브러리 내 함수 --> 설명
2.1 lazy()는 람다를 전달받아 저장한 Lazy<T> 인스턴스를 반환
2.2 최초 getter 실행은 lazy()에 넘겨진 람다를 실행하고, 결과를 기록
2.3 이후 getter 실행은 기록된 값을 반환
즉, lazy는 프로퍼티의 값에 접근하는 최초 시점에 초기화를 수행하고 이 결과를 저장한 뒤 기록된 값을 재반환하는 인스턴스를 생성하는 함수이다.
3. Run and check Result
1 2 3 4 5 6 7 8 9 10 11 | package com.javasampleapproach.lazyinit fun main(args: Array<String>) { val person = Person("Andrien") println(person.books) println("--- call again ---") println(person.books) } | cs |
'Kotlin' 카테고리의 다른 글
4. Delegated Property - Observable Property (0) | 2018.05.30 |
---|---|
2. Java Static Method equivalent in Kotlin (0) | 2018.05.30 |
1. Immutable & Mutable - Val vs Var (0) | 2018.05.30 |