如何通过反射引用及遍历Kotlin中的重载顶层函数
Kotlin 反射遍历重载顶层函数的实现方案
核心原理
Kotlin 所有顶层函数在编译后,都会被封装为对应Kotlin源文件生成的JVM类的公共静态方法:
- 无特殊注解的情况下,生成类的命名规则为
源文件名首字母大写 + Kt,例如Utils.kt生成的类为UtilsKt - 如果源文件添加了
@file:JvmName("自定义类名")注解,生成类的名称就是注解中指定的名称
具体实现步骤
1. 自有项目内的顶层函数遍历
如果是你自己代码中定义的顶层函数,直接引用生成类即可,示例如下:
假设你在Demo.kt中定义了三个重载的foo顶层函数:
// Demo.kt 内容 fun foo(x: Int) = Unit fun foo(x: Byte) = Unit fun foo(x: Float) = Unit
遍历所有重载版本的代码:
import kotlin.reflect.full.staticFunctions fun main() { // 直接引用Demo.kt生成的类 DemoKt::class.staticFunctions .filter { it.name == "foo" } .forEach { println(it) } }
执行后会输出三个重载的foo函数信息。
2. 第三方库/标准库顶层函数遍历(以kotlin.io.println为例)
对于标准库或者第三方模块中的顶层函数,你可以先通过Class.forName拿到对应生成类的Java类,再转为KClass处理:
import kotlin.reflect.jvm.kotlin import kotlin.reflect.full.staticFunctions fun main() { // 获取kotlin.io包下println所属的生成类 val ioTopClass = Class.forName("kotlin.io.ConsoleKt").kotlin // 过滤所有名为println的静态重载函数 ioTopClass.staticFunctions .filter { it.name == "println" } .forEach { println(it) } }
执行后会输出所有重载版本的println函数信息。
备用方案:Java反射实现
如果不想依赖Kotlin反射库,也可以直接用Java反射实现相同效果:
import java.lang.reflect.Modifier fun main() { val methods = Class.forName("kotlin.io.ConsoleKt").methods methods.filter { it.name == "println" && Modifier.isStatic(it.modifiers) }.forEach { println(it) } }
常见错误说明
你之前尝试通过::main::class访问的是main函数可调用引用对象的类型,不是顶层函数所属的源文件生成类,因此会抛出合成类无法访问的异常,只要定位到正确的源文件生成类即可解决问题。
内容的提问来源于stack exchange,提问作者Dan Lugg
相关产品推荐
相关产品推荐

