Home > Software design >  Kotlin set lazy field through Java reflection
Kotlin set lazy field through Java reflection

Time:06-28

I'm trying to play around with Java reflection in Kotlin, and I have the following field in my Kotlin class:

val tree: Tree by lazy { 
    getTree(hashGroup, service) 
}

I'd like to set this field through Java reflection, and so far I got to this point:

val tField = transaction::class.java.getDeclaredField("tree\$delegate")
tField.isAccessible = true
tField.set(transaction, newTree)

Obviously this is not going to work, because the tree field has a delegate (tree$delegate) and it wants me to set it to a Lazy class type and not Tree type.

I know the easiest would be to actually add a setter for this field in the main class but I can't really modify the API and I need this for a resilience test case. Is this even possible to do?

CodePudding user response:

Just create a Lazy<T> instance like you normally would!

If you want to set it to the constant value newTree:

tField.set(transaction, lazyOf(newTree))

You can also set a new block of code for it to be evaluated lazily:

tField.set(transaction, lazy {
    Tree().apply {
        // do something lazily to this tree...
    }
})
  • Related