ayvango
ayvango

Reputation: 5977

Modify immutable scala class field via reflection

I need to modify public immutable field (with val qualifier) in an existing object imported from a scala library which I can not modify through source code. How can it be done with reflection functionality? There are ways to modify final field in java, so there should be one for scala as well, but I'm not sure about it.

final class Example(src : String) {
  lazy val internal = src
}

The internal field is AnyRef if it matters.

P.S. I understand that I'm craving for desperate measure.

Upvotes: 1

Views: 720

Answers (1)

Régis Jean-Gilles
Régis Jean-Gilles

Reputation: 32739

Desperate measure you want, desperate measure youu get:

import scala.util._
def modifyField( obj: AnyRef, name: String, value: Any ) {
  def impl(clazz: Class[_] ) {
    Try(clazz.getDeclaredField(name)).toOption match {
      case Some(field) => 
        field.setAccessible(true)
        clazz.getMethod(name).invoke(obj) // force init in case it's a lazy val
        field.set(obj, value) // overwrite value
      case None => 
        if (clazz.getSuperclass != null) {
          impl(clazz.getSuperclass)
        }
    }
  }
  impl(obj.getClass)
}

Upvotes: 6

Related Questions