En Java, cuando tengo una instancia de Class<>, tengo getMethod que devuelve un método y es muy fácil de usar. Como puedo ver, Kotlin hace la vida más difícil porque ese método no existe. ¿Existe una buena manera de obtener un método específico además de convertir KClass en Class y luego usarlo exactamente como en Java?
Suponiendo que tienes esta clase:
class Test { fun sayHello() = println("Hello world") companion object { fun foo() = println("foo") } } Esto le brinda una instancia de función a la que puede llamar con invoke() (que es una función de operador, por lo que puede usar paréntesis como con cualquier otra función. Si obtiene la función usando el nombre de clase como este, no está vinculado a un instancia. Entonces, pasa la instancia como el primer parámetro al invocar. (Si sayHello() tuviera parámetros adicionales, simplemente irían después del primer parámetro de Prueba).
val sayHelloFunction = Test::sayHello val test = Test() helloWorldFunction(test) // same as calling test.sayHello()También puede obtener una referencia de función vinculada a una instancia como esta. No se puede llamar en otras instancias de Test.
val test = Test() val sayHelloFunction = test::sayHello helloWorldFunction() // same as calling test.sayHello()El método anterior no requiere la biblioteca de reflexión de Kotlin.
Para obtener un miembro por nombre de cadena, no hay una función específica como getMethod de Java, por lo que debe elegirlo de la lista de miembros, que son KCallable. KCallable no tiene el operator fun invoke , por lo que debe usar call para llamarlo o convertirlo en un tipo de función específico (en este caso sería (Test) -> Unit ).
val sayHelloCallable = Test::class.members.single { it.name == "sayHello" } val test = Test() sayHelloCallable.call(test) // same as calling test.sayHello()Esto no enumera los miembros del objeto complementario, ya que es una clase diferente. Para eso tendrías que sacar la clase del compañero:
Test.Companion::class.members.single { it.name == "foo" }No sé si hay una manera de obtener una versión vinculada a la instancia por nombre.
En cuanto a por qué no hay una función getMethod conveniente para KClass, solo puedo suponer que debido a que las clases de Kotlin tienen tantos tipos diferentes de miembros (propiedades, funciones, delegados, campos de respaldo), tal vez quieran limitar el exceso de API y sentir que el en línea las funciones de filtrado como single son adecuadas.