How to set delegated property value by reflection in kotlin?

11,281

If you want to reflectively set the property as if it was record.name = "...", then you can use kotlin-reflect, the Kotlin reflection API (see the reference).

With kotlin-reflect, setting a property value is done like this:

val property = outputs::class.memberProperties.find { it.name == "name" }
if (property is KMutableProperty<*>) {
    property.setter.call(record, "value")
}

If the property is delegated, the call will be dispatched to the delegate.

Or, you can do that with Java reflection, finding the setter for your property first:

var setter = clazz.getDeclaredMethod("set" + it.capitalize())
setter.invoke(record, "aa")

But there is no way, at least at this point, to overwrite the delegate instance of that property, because the field storing it, name$delegate, is final.

Share:
11,281

Related videos on Youtube

junk
Author by

junk

Junk coder, keep learning, plz don't laugh at my code.

Updated on June 07, 2022

Comments

  • junk
    junk almost 2 years

    My entity class:

    class User : ActiveRecord<User>() {
        var name by Column(String.javaClass);
        var id by Column(Int.javaClass);
    }
    

    now I want to set name value by refelection:

    var clazz = User().javaClass
    var record = clazz.newInstance()
    var field = record.getDeclaredField(it + "$" + "delegate")
    
    field.set(record, "aa")
    

    then error:

    entity.Column field ActiveRecord4k.User.name$delegate to java.lang.String

    how to do this?

    • hotkey
      hotkey almost 7 years
      Are you trying to replace the delegate with another instance, or just reflectively set the property value like record.name = "aa"?
  • junk
    junk almost 7 years
    Callable expects 2 arguments ? why ? what is the kotlin-reflect version?
  • hotkey
    hotkey almost 7 years
    Oh, it was a mistake in the code, you should actually pass the object and the property value: property.setter.call(record, "value"). Fixed this.