kotlin 通过反射调用数据类copy

qoefvg9y  于 2022-12-23  发布在  Kotlin
关注(0)|答案(2)|浏览(111)

是否可以在Kotlin中通过反射调用一个数据类的copy()函数?如何获得对函数本身的引用?是否所有数据类都有一个超类?

lyfkaqu1

lyfkaqu11#

对于所有data类,没有通用的超类型。
基本上,copy是一个普通的成员函数,您可以使用Kotlin reflection API调用它,如下所示:

val person = Person("Jane", 23)
val copy = person::class.memberFunctions.first { it.name == "copy" }
val instanceParam = copy.instanceParameter!!
val ageParam = copy.parameters.first { it.name == "age" }
val result = copy.callBy(mapOf(instanceParam to person, ageParam to 18))
println(result) // Person(name=Jane, age=18)

确保将kotlin-reflect添加为依赖项。
上面的示例说明了如何省略默认参数的值-不为name传递值。如果要传递所有参数,可以用更简单的方法完成:

val person = Person("Jane", 23)
val copy = person::class.memberFunctions.first { it.name == "copy" }
val result = copy.call(person, person.name, 18)
println(result) // Person(name=Jane, age=18)

Kotlin反射API对于调用函数来说不是绝对必要的,如果你为所有参数传递实参,你也可以通过Java反射来实现:

val person = Person("Jane", 23)
val copy = person::class.java.methods.first { it.name == "copy" }
val result = copy.invoke(person, person.name, 18)
println(result) // Person(name=Jane, age=18)
ojsjcaue

ojsjcaue2#

因此,根据https://stackoverflow.com/users/2196460/hotkey的上述回答:

fun <T : Any> clone (obj: T): T {
  if (!obj::class.isData) {
    println(obj)
    throw Error("clone is only supported for data classes")
  }

  val copy = obj::class.memberFunctions.first { it.name == "copy" }
  val instanceParam = copy.instanceParameter!!
  return copy.callBy(mapOf(
    instanceParam to obj
  )) as T
}

相关问题