Search code examples
kotlinreflectionmethod-referencekotlin-reflect

How to access the receiver of a method reference?


I have a method reference (represented by the kotlin.reflect.KFunction0 interface). What I would like to do is to get the receiver object of the method reference.

For example:

data class MyClass(val name: String)

val john = MyClass("John")
val methodReference = john::toString

methodReference.receiver // doesn't work!

The receiver of methodReference is the object john. If I look into the IntelliJ debugger, methodReference has a receiver field which indeed points to john. But I cannot find a way to actually access it in my code.

Is there some sort of workaround for this?


Solution

  • Assuming this is Kotlin/JVM, the receiver field you see is a protected field declared in CallableReference. You can get this using Java reflection.

    val f = someINstance::foo
    val receiverField = CallableReference::class.java.getDeclaredField("receiver")
    receiverField.isAccessible = true
    println(receiverField.get(f))
    

    I'm not sure if this field is guaranteed to be called receiver, or whether it will exist at all, in future versions. I cannot find any official documentation on this.

    Also note that not every KFunction0 has a receiver. When this is the case, receiverField.get(f) would return CallableReference.NO_RECEIVER.