2014-05-22 54 views
0

我需要修改从我无法通过源代码修改的scala库导入的现有对象中的公共不可变字段(使用val限定符)。如何用反射功能来完成?有很多方法可以修改java中的final字段,所以scala也应该有一个,但我不确定。通过反射修改不可变的scala类字段

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

如果它很重要,内部字段是AnyRef。

P.S.我明白我渴望绝望的措施。

+0

你有这个库的来源是什么?我不是想修改它们,而是想看看。 –

+0

当然,我拥有它。 http://www.scala-sbt.org/release/sxr/sbt/Defaults.scala.html#sbt.Defaults.config任务 – ayvango

+3

Ooops,事实上它是'懒'可以使事情变得更加困难(使用Java反射几乎是不适用) –

回答

4

你想苦肉计,苦肉计youu得到:

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) 
}