在Kotlin中动态获取名称功能

时间:2016-01-16 06:43:01

标签: reflection kotlin

如何在Kotlin中按名称动态获取函数?

即:

fun myFunc11() { println("Very useful function 11") }

val funcName = "myFunc" + 11
val funcRef = getFunction(funcName)

funcRef()

编辑:接受的答案似乎是正确的,但是代码目前在Kotlin中遇到了一些错误。错误报告已提交:https://youtrack.jetbrains.com/issue/KT-10690

2 个答案:

答案 0 :(得分:10)

the documentation中所述,名为fun myFunc11() { ... }的文件中定义的Global.kt等全局函数将编译为static类上的GlobalKt方法。

要按名称获取函数引用,您需要加载定义它的类。如果您知道定义函数引用的文件名,那么您可以执行以下操作:

fun getFunctionFromFile(fileName: String, funcName: String): KFunction<*>? {
    val selfRef = ::getFunctionFromFile
    val currentClass = selfRef.javaMethod!!.declaringClass
    val classDefiningFunctions = currentClass.classLoader.loadClass("${fileName}Kt")
    val javaMethod  = classDefiningFunctions.methods.find { it.name == funcName && Modifier.isStatic(it.modifiers)}
    return javaMethod?.kotlinFunction
}

然后你可以找到并调用Global.kt文件中定义的函数:

fun myFunc11() { println("Very useful function 11") }
像这样:

val kFunction = getFunctionFromFile("Global", "myFunc11")
kFunction?.call()

然而,上述情况毫无用处。更好的解决方案是搜索类路径中可用的所有类,并以Kt为后缀,以覆盖所有全局函数。然而,由于jvm类加载器的性质,如this answer中所述,这更加复杂。

答案 1 :(得分:0)

您可以使用 function reference operator

::myFunc11.name