Trying to call lambda provided by MyClass constructor using Kotlin Reflection.
data class MyClass(
var magic:Int=2,
var lambdaValue: ()->String = { //trying to call this lambda from reflection
"Working"
},
)
fun main(args: Array<String>) {
val clazz=MyClass::class
val obj=clazz.createInstance()
val kProperty=clazz.memberProperties
clazz.constructors.forEach{cons-> // for each construtor
cons.parameters.forEach{ parameter-> // looping through constructor parameters
val property=kProperty.find { it.name==parameter.name } // finding the exact property
print(parameter.name " : ")
if(parameter.type.arguments.isEmpty()) // if empty Int,Float
{
println(property?.get(obj))
}else{
println(property?.call(obj)) // unable to call lambda
}
}
}
}
property.call(obj) returns Any which is not invokable. Any solution?
Expected:
magic : 2
lambdaValue : Working
CodePudding user response:
Frankly speaking, I'm not sure what was your idea behind parameter.type.arguments.isEmpty()
. It seems unrelated to what you try to do.
If we have a value of the property already, we can simply check its type and if its is a function then invoke it:
val value = kProperty.find { it.name==parameter.name }!!.get(obj)
print(parameter.name " : ")
when (value) {
is Function0<*> -> println(value())
else -> println(value)
}
I think usefulness of such a code in generic case isn't very high. This code doesn't know what is the function and if it is going to return a value or perform some action, etc. Maybe in your specific case it is more useful.