为何KClass::memberExtensionFunctions始终为空?附代码及空输出现象
问题分析与解决方案
嘿,这个问题我之前踩过坑!核心原因是你搞混了declaredMemberExtensionFunctions和memberExtensionFunctions这两个反射属性的作用范围——它们只能获取声明在类内部的成员扩展函数,而不是你写在顶层的那种全局扩展函数。
你定义的fun FooBar.baz()是顶层扩展函数,它本质上是属于所在Kotlin文件生成的隐含类(比如你的文件名叫Main.kt,对应的隐含类就是MainKt)的静态方法,和FooBar类本身没有成员归属关系。所以用FooBar::class去调用那两个属性,自然拿不到任何结果。
解决方案1:把扩展函数改成类内部的成员扩展函数
如果你的业务场景允许,可以把扩展函数声明在FooBar类内部,这样它就会被视为FooBar的成员扩展函数,就能被目标反射属性捕获到了:
import kotlin.reflect.full.* class FooBar(val bar: String) { // 声明在类内部的成员扩展函数 fun FooBar.baz(): Unit { println(this.bar) } } fun main(args: Array<String>) { FooBar::class.declaredMemberExtensionFunctions.forEach { println(it) } // 现在会输出:fun FooBar.baz(): kotlin.Unit }
解决方案2:正确获取顶层扩展函数
如果想保留顶层扩展函数的写法,要获取它的话,得通过它所在的文件隐含类来反射,再过滤出接收者为FooBar的函数:
import kotlin.reflect.full.* class FooBar(val bar: String) fun FooBar.baz(): Unit { println(this.bar) } fun main(args: Array<String>) { // 替换成你的Kotlin文件名对应的隐含类(比如文件叫Test.kt就是TestKt::class) val topLevelClass = MainKt::class topLevelClass.declaredFunctions.forEach { function -> // 过滤出接收者类型为FooBar的扩展函数 if (function.extensionReceiverParameter?.type == FooBar::class.createType()) { println(function) } } // 输出:fun FooBar.baz(): kotlin.Unit }
总结一下:顶层扩展函数不属于目标类的成员,而是绑定到所在文件的隐含类;只有定义在类内部的成员扩展函数,才会被declaredMemberExtensionFunctions和memberExtensionFunctions这两个属性识别到。
内容的提问来源于stack exchange,提问作者jilen
相关产品推荐
相关产品推荐

