如何获取Kotlin方法引用的receiver对象?
获取KFunction0绑定的Receiver对象
当你像john::toString这样创建绑定了接收者的方法引用时,它虽然实现了KFunction0接口,但Kotlin标准库并没有公开暴露内部的receiver属性——调试器能看到是因为内部确实存在这个字段,只是没开放访问权限。要拿到这个接收者对象,只能通过反射来读取内部字段。
解决代码示例
先写一个工具函数封装反射逻辑:
import kotlin.reflect.KFunction0 fun <T> KFunction0<*>.getBoundReceiver(): T? { return runCatching { val receiverField = this::class.java.getDeclaredField("receiver") receiverField.isAccessible = true @Suppress("UNCHECKED_CAST") receiverField.get(this) as T }.getOrNull() }
然后直接调用这个扩展函数就能拿到接收者:
data class MyClass(val name: String) fun main() { val john = MyClass("John") val methodReference = john::toString val receiver = methodReference.getBoundReceiver<MyClass>() println(receiver?.name) // 输出 John }
注意事项
- 这种方式依赖Kotlin反射的内部实现,不同Kotlin版本可能会修改内部字段名,存在兼容性风险。
- 如果传入的
KFunction0是顶层函数或未绑定接收者的方法引用(比如MyClass::toString),函数会返回null。 - 反射操作需要处理访问权限问题,这里用
runCatching和isAccessible = true来规避异常和权限限制。
内容的提问来源于stack exchange,提问作者Martin Häusler
相关产品推荐
相关产品推荐

