Reputation: 5977
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
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