¿Cómo puedo establecer una propiedad de un object complementario en Kotlin a través de la reflexión?
Cuando tengo una class que tiene un object complementario, ¿es posible establecer una propiedad en este object complementario mediante la reflexión? Puedo hacerlo con properties normales, pero fallar en objects complementarios:
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()) }
Llamar al colocador por la propiedad normal funciona como debería, pero cuando llamo a companionProp.setter.call(companionProp, "hello")
obtengo
- Kotlin: ¿Es aquí una forma inteligente de lanzar NotImplementedError para todos los methods de una class?
- Configurar la reflexión de kotlin, class.java no funciona
- ¿Cómo obtengo una KProperty1 de una KProperty0?
- java.lang.IllegalArgumentException: Callable espera 4 arguments, pero se proporcionaron 3
- por qué SomeClass :: class es KClass <SomeClass> pero esta :: class es KClass <out SomeClass>
Excepción en el hilo "main" java.lang.IllegalArgumentException: object no es una instancia de class declarante
¿Qué tengo que pasar como primer argumento para call()
para tener éxito?
Editar: escribí companionProp
como primer argumento, pero definitivamente está mal, en realidad lo intenté con el object companion
, pero eso tampoco funciona.
- String.intern () devuelve diferentes valores en un controller JDBC
- ¿Cómo get los nombres de los parameters a través de la reflexión en kotlin?
- Obtén la function por nombre dinámicamente en Kotlin
- Obteniendo la class actual
- ¿El comstackdor de Kotlin siempre conserva los nombres de los parameters en bytecode?
- ¿Cómo puedo get el nombre de una propiedad de Kotlin?
- Cómo acceder a los objects-miembros de una statement de object en kotlin
- ¿Hay alguna manera de identificar una class de datos Kotlin de una class regular de Kotlin?
object no es una instancia de declarar class
Al igual que en Java, debe pasar el object en sí mismo como primer parámetro al llamar a methods reflexivos.
El primer parámetro para call
debe ser el object complementario, ya que ese es el object cuya propiedad está tratando de modificar.
Está pasando el object de class del acompañante en lugar del propio object complementario.
Se puede acceder a un object complementario a través de ClassName.Companion
, o cuando se usa una reflexión adicional, a través de KClass#companionObjectInstance
.
companionProp.setter.call(WithProperty.Companion, "hello") companionProp.setter.call(obj::class.companionObjectInstance, "hello") companionProp.setter.call(WithProperty::class.companionObjectInstance, "hello")
Cuando se ejecutan, ambas variantes imprimen hello world
como se esperaba.
Tenga en count que Foo.Companion
provocará un error de compilation si el object complementario no existe, mientras que la variante reflectante devolverá null
lugar.
el primer argumento es la instancia de la class declarante.
pasa una instancia de KProperty
companionProp
lugar de una instancia de object complementario. Sin embargo, puede usar KClass.companionObjectInstance
para get la instancia de compañía. por ejemplo:
//a non-static property having a receiver, so it should be a KMutableProperty1 here // v if (companionProp is KMutableProperty1<*, *>) { // get the companion object instance ---v companionProp.setter.call(obj::class.companionObjectInstance, "hello") }
- ¿Cómo crear un IntArray de tamaño fijo e inicializar el array más adelante en Kotlin?
- Kotlin: Intrinsics.areEqual loop infinito (desbordamiento de stack)