Home > Net >  How to call constructor default lambda using Kotlin Refelction?
How to call constructor default lambda using Kotlin Refelction?

Time:01-08

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.

  • Related