通过反射调用数据class copy()
Call data class copy() via reflection
就是这样。是否可以通过 Kotlin 中的反射调用数据 class 的 copy() 函数?我怎样才能引用函数本身?是否有一个superclass 用于所有数据classes? (找不到了...)
所有 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)
因此,根据 https://whosebug.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
}
就是这样。是否可以通过 Kotlin 中的反射调用数据 class 的 copy() 函数?我怎样才能引用函数本身?是否有一个superclass 用于所有数据classes? (找不到了...)
所有 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)
因此,根据 https://whosebug.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
}