Search code examples
reflectionkotlincopydata-class

Call data class copy() via reflection


Is it possible to call the copy() function of a data class via reflection in Kotlin? How can I get a reference to the function itself? Is there a superclass for all data classes?


Solution

  • There's no common supertype for all data classes.

    Basically, copy is a normal member function which you can call with the Kotlin reflection API as follows:

    val person = Person("Jane", 23)
    val copy = person::class.memberFunctions.first { it.name == "copy" }
    val instanceParam = copy.instanceParameter!!
    val ageParam = copy.parameters.first { it.name == "age" }
    val result = copy.callBy(mapOf(instanceParam to person, ageParam to 18))
    println(result) // Person(name=Jane, age=18)
    

    Make sure you add kotlin-reflect as a dependency.

    The example above shows how to omit values for the default parameters – no value is passed for name. If you want to pass all the parameters, this can be done in a simpler way:

    val person = Person("Jane", 23)
    val copy = person::class.memberFunctions.first { it.name == "copy" }
    val result = copy.call(person, person.name, 18)
    println(result) // Person(name=Jane, age=18)
    

    Kotlin reflection API is not strictly necessary to call a function if you pass arguments for all of the parameters, you can do that via Java reflection as well:

    val person = Person("Jane", 23)
    val copy = person::class.java.methods.first { it.name == "copy" }
    val result = copy.invoke(person, person.name, 18)
    println(result) // Person(name=Jane, age=18)