如何在 Kotlin 中从 KClass 获取方法

问题描述 投票:0回答:2

在java中,当我有一个Class<>实例时,我有一个返回方法的getMethod,它非常容易使用。 正如我所见,Kotlin 让生活变得更加困难,因为这样的方法不存在。除了将 KClass 转换为 Class 然后像在 Java 中一样使用它之外,还有什么好方法来获取特定方法吗?

java android class kotlin reflection
2个回答
4
投票

假设你有这门课:

class Test {
    fun sayHello() = println("Hello world")

    companion object {
        fun foo() = println("foo")
    }
}

这为您提供了一个可以使用

invoke()
调用的函数实例(这是一个运算符函数,因此您可以像使用任何其他函数一样使用括号。如果您使用这样的类名获取函数,则它不会绑定到一个实例。因此,您在调用时将实例作为第一个参数传递。(如果
sayHello()
有其他参数,它们将只跟随 Test 的第一个参数。)

val sayHelloFunction = Test::sayHello
val test = Test()
sayHelloFunction(test) // same as calling test.sayHello()

您还可以获得绑定到实例的函数引用,如下所示。不能在 Test 的其他实例上调用它。

val test = Test()
val sayHelloFunction = test::sayHello
sayHelloFunction() // same as calling test.sayHello()

上述方法不需要Kotlin反射库。

要通过字符串名称获取成员,没有像Java的

getMethod
那样的特定函数,因此您必须从成员列表中选择它,这些成员是KCallable。 KCallable 没有
operator fun invoke
,因此您必须使用
call
来调用它,或者将其转换为特定的函数类型(在本例中为
(Test) -> Unit
)。

val sayHelloCallable = Test::class.members.single { it.name == "sayHello" }
val test = Test()
sayHelloCallable.call(test) // same as calling test.sayHello()

不会列出伴生对象的成员,因为那是一个不同的类。为此,您必须获得同伴的班级:

Test.Companion::class.members.single { it.name == "foo" }

我不知道是否有办法通过名称获取实例绑定版本。

至于为什么 KClass 没有方便的

getMethod
函数,我只能猜测,因为 Kotlin 类有很多不同类型的成员(属性、函数、委托、支持字段),也许他们想限制 API 的膨胀和感觉像
single
这样的内联过滤功能就足够了。


0
投票

要从

Class
获取
KClass
,您只需在其上调用
.java
(然后按
.kotlin
走另一条路)。

© www.soinside.com 2019 - 2024. All rights reserved.