ABOUT ME

Today
Yesterday
Total
  • kotlin delegated properties
    Kotlin/Kotlin 2024. 3. 1. 00:01
    반응형

    개요

    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' 카테고리의 다른 글

    댓글

Designed by Tistory.