gpt4 book ai didi

reflection - 如何通过反射使用 Kotlin 对象

转载 作者:IT老高 更新时间:2023-10-28 13:46:59 26 4
gpt4 key购买 nike

假设我需要通过反射在 Kotlin 对象 O 中设置由字符串给定的属性 A。如果 O 是一个类,我可以做这样的事情(忽略它没有意义):

fun setValue(ownerClassName: String, fieldName: String, value : Any) {
val enclosingClass = Class.forName(ownerClassName).newInstance()
val enclosingClassField = enclosingClass.javaClass.getDeclaredField(fieldName)
enclosingClassField.isAccessible = true
enclosingClassField.set(enclosingClass, value)
}

但是如果 O 是一个对象,我该怎么做呢?

最佳答案

KClass 有一个 objectInstance字段:

Class.forName(ownerClassName).kotlin.objectInstance

这是内置在 Kotlin 反射中的。

Returns: The instance of the object declaration, or null if this class is not an object declaration.

如果KClass 有一个forName 方法会更好,但遗憾的是does not (然而),所以我们需要获取 (Java) Class 并将其转换为 KClass

您可以使用 .kotlin 扩展属性从 Class 获取 KClass 实例。

然后您可以继续使用其余代码。我将其转换为 Kotlin 的反射库:

val kClass = Class.forName(ownerClassName).kotlin
// Get the object OR a new instance if it doesn't exist
val instance = kClass.objectInstance ?: kClass.java.newInstance()

val member = kClass.memberProperties
// Has to be a mutable property, otherwise we can't set it
.filterIsInstance<KMutableProperty<*>>()
// Check the name
.filter { it.name == fieldName }
.firstOrNull()

// Set the property
member?.setter?.call(instance, value)

这是一个工作测试:

object TestObject {
var field = 3
}

fun setValue(ownerClassName: String, fieldName: String, value: Any) {
val kClass = Class.forName(ownerClassName).kotlin
val instance = kClass.objectInstance ?: kClass.java.newInstance()

val member = kClass.memberProperties.filterIsInstance<KMutableProperty<*>>()
.firstOrNull { it.name == fieldName }

member?.setter?.call(instance, value)
}

fun main(args: Array<String>) {
println(TestObject.field) // 3
setValue("some.package.TestObject", "field", 4)
println(TestObject.field) // 4
}

关于reflection - 如何通过反射使用 Kotlin 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47675033/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com