How to access the receiver of a method reference?

85 views Asked by At

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?

1

There are 1 answers

1
Sweeper On BEST ANSWER

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.