2014-05-22 56 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) 
}