본문으로 바로가기

3. Lazy Initialization

category Kotlin 2018. 5. 30. 17:44

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