¿Cómo obtengo el valor de una propiedad con reflection?

Quiero usar los valores de todas las properties que tienen alguna anotación. En general, mi código funciona, obtengo todas las properties y solo tomo aquellas que tienen esa anotación.

private inline fun <reified A : Annotation> (target: Any) { target::class.memberProperties .filter { it.annotations.any { annotation -> annotation is A } } .forEach { // How do I get the value here? } } 

Quería usar it.get(...) pero get espera un parámetro Nothing como. Lo mismo ocurre con getter . Llamar a it.call(target) funciona, pero se ve mal, ya que hay un reall get que no sé cómo invocar.

Entonces, ¿cuál es la forma correcta de get el valor de las properties?

El problema se networkinguce al hecho de que T::class te da una KClass<T> , mientras que t::class te da una KClass<out T> . Considera lo siguiente:

 class Foo { val foo = 2 val bar = 3 } fun f() { val any: Any = Foo() any::class.memberProperties.forEach { println(it.get(2)) // Oops } } 

Esto esencialmente intentaría acceder a 2.foo y 2.bar , pero no está permitido porque get equivoca por el lado de la precaución en lugar de permitir un parámetro de tipo Any . Parece que t.javaClass.kotlin producirá una KClass<T> , sin embargo. Mal uso como arriba causa una IllegalArgumentException .

Puede brindar más ayuda al comstackdor al proporcionarle una garantía en time de compilation de que KClass será para el tipo y nada más:

 private inline fun <reified A : Annotation, reified T : Any> foo(target: T) { T::class.memberProperties .filter { it.annotations.any { annotation -> annotation is A } } .forEach { println(it.get(target)) } } 

Lamentablemente, no sé si es posible especificar A al deducir T del target . No he encontrado una manera de llamarlo pasado como foo<Attr, Bar>(bar) .

Alternativamente, puedes pasar por javaClass , aunque javaClass que es less portátil:

 private inline fun <reified A : Annotation> foo(target: Any) { target.javaClass.kotlin.memberProperties .filter { it.annotations.any { annotation -> annotation is A } } .forEach { println(it.get(target)) } } 

Sabemos que esto no se encontrará con el problema anterior porque pasamos el mismo object en ambos casos. Esto también se ve mejor por el lado de la persona que llama, que podría valer la pena el golpe de portabilidad, suponiendo que haya uno.

  • por qué SomeClass :: class es KClass <SomeClass> pero esta :: class es KClass <out SomeClass>
  • ¿Cómo get los nombres de los parameters a través de la reflexión en kotlin?
  • Kotlin: isAssignableFrom y reflexiones del tipo de reflexión
  • ¿Cómo get la reference de class de KParameter en kotlin?
  • Determinar si una instancia es una instancia de una class de datos
  • ¿Cómo get un KType en Kotlin?
  • ¿El comstackdor de Kotlin siempre conserva los nombres de los parameters en bytecode?
  • String.intern () devuelve diferentes valores en un controller JDBC
  • ¿Cómo puedo establecer una propiedad de un object complementario en Kotlin a través de la reflexión?
  • Acceda al tipo de delegado de Kotlin sin una instancia
  • Kotlin enlazó la incoinheritance de las references invocables