7

就是这样。是否可以通过 Kotlin 中的反射调用数据类的 copy() 函数?我怎样才能引用函数本身?所有数据类都有超类吗?(我找不到……)

4

2 回答 2

17

所有类都没有共同的超类型data

基本上,copy它是一个普通的成员函数,您可以使用Kotlin 反射 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)
于 2018-03-27T11:07:29.617 回答
1

因此,基于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
}


于 2019-11-13T16:33:03.337 回答