ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • kotlin delegated properties
    Kotlin/Kotlin 2024. 3. 1. 00:01
    728x90

    개요

    class Example {
        var p: String by Delegate()
    }

    kotlin을 활용하다 보면 by 키워드등이 활용되는 예시를 만난 적들이 있으며 해당 문법을 잘 모르는 상황에서 당황스러운 경험들이 있습니다.

    kotlin delegated property에 대해 이해하기 위해 글을 작성해보가 합니다.

     

    Delegated Properties란?

    delegated는 "위임된" 이라는 뜻을 가집니다.

    즉 프로퍼티의 속성을 미리 정의된 다른 속성에게 위임한다는 의미를 가집니다.

    Kotlin에서는 by 키워드를 활용하여 프로퍼티의 위임을 수행할 수 있습니다.

     

    Interface의 구현체를 다른 객체에게 위임할 수 있고, Property의 Accessor 구현을 다른 객체의 위임할 수도 있습니다.

    Accessor는 접근자를 뜻하며 Setter, Getter를 뜻합니다.

     

    Why Delegated Properties

    한번 구현하여 라이브러리 추가한 후 나중에 재사용한 것이 유용합니다.

    예를 들면 lazy properties, observable properties 등이 존재하고 사용자가 직접 XX properties를 정의해서 재사용할 수 있습니다.

     

     

    Delegated를 한다는 것은 어떤 의미인가?

    다른 객체에서 구현된 getValue, setValue  (getter, setter)를 활용한다는 이야기입니다.

    다만 불변객체 val이라면 setter를 구현해 줄 필요는 없습니다.

     

    직접 Delegated Property 만들어보기

    private class LoggingProperty<T>(var value: T){
        operator fun getValue(
                thisRef: Any?,
                prop: KProperty<*>,
        ): T{
            println("property [${prop.name}]의 조회가 감지되었습니다. 조회된 값[$value]")
            return value
        }
    
        operator fun setValue(
                thisRef: Any?,
                prop: KProperty<*>,
                newValue: T,
        ) {
            val name = prop.name
            println("property [$name]의 변경이 감지되었습니다. 기존값[$value] 변경값[$newValue]")
            value = newValue
        }
    }

    여러 변수를 받아야 하므로 제네릭으로 value를 선언해 주고 getValue, setValue에 해당하는 operator를 선언해 줍니다.

    해당 Delegated Property는 로깅을 지원하는 프로퍼티로써 get, set이 일어날 때 변경을 감지하여 해당 값을 출력해 줍니다.

     

    thisRef는 프로퍼티가 속한 클래스에 대한 참조입니다.

    KProperty는 위임되는 속성에 대한  reflection입니다.

    prop.name을 통해서 property의 이름을 가져올 수 있습니다.

     

    테스트를 통해 알아보기

    @Test
    fun `Delegated Property를 직접 만들어보자`(){
    	var token: String? by LoggingProperty(null)
    	token = "hi"
    	println("어떤 일이 벌어질까요?")
    	val getToken = token
    }
    
    //출력
    property [token]의 변경이 감지되었습니다. 기존값[null] 변경값[hi]
    어떤 일이 벌어질까요?
    property [token]의 조회가 감지되었습니다. 조회된 값[hi]
    token이라는 프로퍼티를 by 키워드를 활용하여 LoggingProperty를 위임하였습니다.
    이제 LoggingProperty의 get, set의 구현에 감싸져서 동작할것이며 get,set이 일어날때 마다 출력이 되는것을 확인할 수 있습니다.

     

     

     

     

    참고자료

    https://junuuu.tistory.com/637

    https://kotlinlang.org/docs/delegated-properties.html

    https://www.baeldung.com/kotlin/delegated-properties

    https://thdev.tech/kotlin/2020/11/27/kotlin_delegation/

     

    'Kotlin > Kotlin' 카테고리의 다른 글

    Kotlin associateBy, groupBy 함수  (0) 2024.03.09
    kotlin interface default method  (0) 2024.03.05
    Kotlin 제네릭에 대해 알아보기  (1) 2024.02.29
    kotlin operator fun invoke  (0) 2024.02.19
    Kotlin Synchonized와 MultiThread  (0) 2023.11.22

    댓글

Designed by Tistory.