Kotlin通过反射调用伴随函数

时间:2019-11-29 16:07:24

标签: kotlin

我是Kotlin的新手。面对反射和泛型的问题。下面是我的代码。

abstract class Action {
  fun sleep(body: Person.() -> Unit){
    var p = Person("a");
    p.body()
    println(p.name + " is zzzzzzz...")
  }
}

class Person(var name:String =""){
  companion object:Action();
}

inline fun <reified T> test(){
  val companionObject = T::class.companionObject
  if (companionObject != null) {
    println(companionObject.javaObjectType)
    val functionEx = companionObject.functions.filter { it.name.equals("sleep") }.first()
    // How to invoke functionEx with block and "this"
  }
}

fun main(args: Array<String>) {
  Person.sleep {
    this.name = "abc"
  }
  test<Person>()
}

我想通过sleep调用functionEx函数,其功能与主体中的相同。我正在与this运算符作斗争。

我正在使用某些API,并通过ActionPerson模拟了该问题。因此无法更改其实现。只是test函数在我的控制之下。

1 个答案:

答案 0 :(得分:2)

这应该有效:

inline fun <reified T> test() {
    val companionObject = T::class.companionObject
    if (companionObject != null) {
        val body: Person.() -> Unit = { println("body called on $name!") }
        val companionInstance = T::class.companionObjectInstance
        val functionEx = companionObject.functions.first { it.name.equals("sleep") }
        functionEx.call(companionInstance, body)
    }
}

要使用call(...)调用函数,您需要将伴随对象实例作为第一个参数(代表sleep函数的接收方)和function type { {1}}作为第二个。

请注意,companionObject不返回伴随对象实例,而是返回其Person.() -> Unit。要获取实例,请改用companionObjectInstance