在java中,当我有一个Class<>实例时,我有getMethod返回一个方法,它非常容易使用。 正如我所见,Kotlin 让生活变得更加困难,因为这样的方法不存在。除了将 KClass 转换为 Class 然后像在 Java 中一样使用它之外,是否有一种很好的方法来获取特定方法?
最佳答案
假设你有这个类(class):
class Test {
fun sayHello() = println("Hello world")
companion object {
fun foo() = println("foo")
}
}
这为您提供了一个可以使用 invoke()
调用的函数实例(这是一个运算符函数,因此您可以像使用任何其他函数一样使用括号。如果您使用该类获取该函数像这样的名称,它没有绑定(bind)到实例。因此,在调用时将实例作为第一个参数传递。(如果 sayHello()
有其他参数,它们只会在 Test 的第一个参数之后.)
val sayHelloFunction = Test::sayHello
val test = Test()
sayHelloFunction(test) // same as calling test.sayHello()
您还可以获得绑定(bind)到实例的函数引用,如下所示。不能在 Test 的其他实例上调用它。
val test = Test()
val sayHelloFunction = test::sayHello
sayHelloFunction() // same as calling test.sayHello()
上述方法不需要Kotlin反射库。
要通过字符串名称获取成员,没有像 Java 的 getMethod 那样的特定函数,因此您必须从成员列表中选择它,这些成员是 KCallable。 KCallable 没有 operator fun invoke
,因此您必须使用 call
来调用它,或者将其转换为特定的函数类型(在本例中它将是 (测试)-> 单元
)。
val sayHelloCallable = Test::class.members.single { it.name == "sayHello" }
val test = Test()
sayHelloCallable.call(test) // same as calling test.sayHello()
此没有列出伴生对象的成员,因为那是一个不同的类。为此,您必须获得同伴的类(class):
Test.Companion::class.members.single { it.name == "foo" }
我不知道是否有办法通过名称获取实例绑定(bind)版本。
至于为什么 KClass 没有方便的 getMethod
函数,我只能猜测,因为 Kotlin 类有很多不同类型的成员(属性、函数、委托(delegate)、支持字段),也许它们想要限制 API 膨胀,并认为像 single
这样的内联过滤函数就足够了。
关于java - 如何在 Kotlin 中从 KClass 获取方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64921081/