通过反射修改不可变的Scala类字段

ayv*_*ngo 1 java reflection scala

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

final class Example(src : String) {
  lazy val internal = src
}
Run Code Online (Sandbox Code Playgroud)

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

PS我知道我渴望采取绝望的措施。

Rég*_*les 5

你想要的绝望措施,你得到的绝望措施:

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)
}
Run Code Online (Sandbox Code Playgroud)