Search code examples
kotlinreflection

How to call constructor default lambda using Kotlin Refelction?


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

Solution

  • 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.