当我有一个类有一个伴生对象时,是否可以使用反射在这个伴生对象中设置一个属性?我可以使用普通属性来做到这一点,但在伴随对象上失败:
import kotlin.reflect.KMutableProperty
import kotlin.reflect.full.companionObject
import kotlin.reflect.full.memberProperties
class WithProperty {
lateinit var prop: String
companion object {
lateinit var companionProp: String
}
fun test() = "$companionProp $prop"
}
fun main(args: Array<String>) {
val obj = WithProperty()
val prop = obj::class.memberProperties.filter { it.name == "prop" }.first()
if (prop is KMutableProperty<*>) {
prop.setter.call(obj, "world")
}
val companion = obj::class.companionObject
if (companion != null) {
val companionProp = companion.memberProperties.filter { it.name == "companionProp" }.first()
if (companionProp is KMutableProperty<*>) {
companionProp.setter.call(companionProp, "hello") // <-- what must go here as first argument?
}
}
println(obj.test())
}
调用 normal 属性的 setter 可以正常工作,但是当我调用 companionProp.setter.call(companionProp, "hello")
时,我得到了
Exception in thread "main" java.lang.IllegalArgumentException: object is not an instance of declaring class
我必须将什么作为第一个参数传递给 call()
才能成功?
编辑:我将 companionProp
写为第一个参数,但这绝对是错误的,我实际上尝试使用 companion
对象,但那是效果不佳。
最佳答案
object is not an instance of declaring class
就像在Java中一样,调用反射方法时需要将对象本身作为第一个参数传递。
call
的第一个参数应该是伴随对象,因为这是您要修改其属性的对象。
您传递的是同伴的类对象,而不是同伴对象本身。
伴生对象可以通过 ClassName.Companion
访问,或者在使用进一步反射时,通过 KClass#companionObjectInstance
.
companionProp.setter.call(WithProperty.Companion, "hello")
companionProp.setter.call(obj::class.companionObjectInstance, "hello")
companionProp.setter.call(WithProperty::class.companionObjectInstance, "hello")
运行时,两个变体都按预期打印 hello world
。
请记住,如果伴随对象不存在,Foo.Companion
将导致编译错误,而反射变体将返回 null
。
关于reflection - 如何通过反射在 Kotlin 中设置伴生对象的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45056702/