【问题标题】:How to declare a reflection-iterable set of functions in Kotlin?如何在 Kotlin 中声明一组反射可迭代的函数?
【发布时间】:2018-03-27 22:42:03
【问题描述】:

我想声明一组不是类成员函数的 Kotlin 函数(即不引用类实例的“静态”函数)。必须以某种方式声明它们,以便我可以在运行时使用反射对其进行迭代。

我的第一次尝试是像这样写一个文件Commands.kt

fun a(): Int = 42
fun b(): Int = 23

但是,我没有找到一种方法来迭代此文件中的函数。我知道为了 Java 兼容性,将生成一个类CommandsKt,其中包含这些函数作为静态方法。但是,我似乎无法在 Kotlin 中引用该类,也没有找到通过反射遍历 Kotlin 文件的所有实体的方法。

我的第二次尝试是使用一个对象:

object Commands {
    fun a(): Int = 42
    fun b(): Int = 23
}

我现在可以通过Commands::class.declaredMemberFunctions 迭代成员函数。但是,这些函数仍然是成员函数,而不是“静态”(Java 语言)函数(对吗?)。

那么我该如何声明这些函数,使它们既是静态的又可以通过反射进行迭代呢?

【问题讨论】:

    标签: reflection kotlin


    【解决方案1】:

    如果您用@JvmStatic 注释object 中声明的函数,它们将被编译为静态Java 方法。

    【讨论】:

    • 手册如此说。但是,我无法使用Commands::class.staticFunctions 检索它们;相反,它们以Commands::class.functions 的形式提供,实际上采用INSTANCE 参数。
    • 字节码对每个这样的函数都有两种声明——静态的和以INSTANCE为参数的。我猜 Kotlin 的反射只看到了后者……
    • 好吧,我的问题是关于通过反射的可用性,而字节码中存在静态方法对我没有帮助。
    【解决方案2】:

    我似乎无法在 Kotlin 中引用该类

    Class.forName("your.package.CommandsKt") 可以工作(它返回java.lang.Class,而不是KClass;我不确定调用.kotlin 是否可以工作)。

    【讨论】:

    • 调用.kotlin适用于任何Java类,不管它是如何编译的。
    • 我会采用这个解决方案,代码看起来更干净。
    • @yole 很高兴知道。这就是我最初的假设,但后来意识到我只是假设并且没有机会测试。
    • @yole 我在接受这个答案时有点太快了。它实际上不起作用:java.lang.UnsupportedOperationException: Packages and file facades are not yet supported in Kotlin reflection. Meanwhile please use Java reflection to inspect this class。所以如果我想使用 Kotlin 反射,另一个答案是正确的。
    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 2017-05-10
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 2017-12-10
    • 2019-05-28
    • 2017-12-11
    相关资源
    最近更新 更多