Kotlin/Kotlin

kotlin delegated properties

Junuuu 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/