【发布时间】:2014-02-28 20:31:46
【问题描述】:
短版: 给定一个 getter Symbol 我想找到相应的 setter Symbol。
长版:
下面是 Scala 反射的一个小工具类。
我打算用这个类来深拷贝Hibernate Entities(抽象类UUIDEntity的子类)。
我将深拷贝分为两部分,1)对对象图中的每个对象进行值拷贝 2)将孤立的副本连接起来形成一个克隆的对象图。这个问题只涉及第一部分。
让root 成为一个实体。
首先,我要创建root 的值副本,我们称之为copy。值复制意味着我只填写副本中的值字段(参见下面的值字段定义)。
这应该发生在getValueCopy 方法中。
存在 val copy,但在使用 val copy= constructorMirror.apply() 创建后其字段仍为空
所以我需要将root 中的字段复制到copy。为此,我需要获取字段的设置器和获取器(更准确地说,值字段是引用值类的字段,如 Int、String、Long 等)。
到目前为止,我设法找到了值字段的 getter (valueGetters),但是,我的问题是我想找到相应的 setter。但我真的不知道将 setter 与 getter 配对的最佳方法是什么?
使用方法名是唯一的方法吗?那是我天真地做的事,但我的感觉告诉我,一定有更好的方法。
欢迎提出任何建议。感谢阅读。
import scala.reflect.runtime.universe._
import java.util
import model.UUIDEntity
import scala.collection.JavaConversions._
import scala.collection.mutable
case class ReflectionOfEntity(root:AnyRef) {
// require(root.isInstanceOf[UUIDEntity[_]])
val rtmMirror =runtimeMirror(getClass.getClassLoader)
val instanceMirror : InstanceMirror =rtmMirror.reflect(root)
val classSymbol : ClassSymbol =rtmMirror.reflect(root).symbol
val classMirror : ClassMirror =rtmMirror.reflectClass(classSymbol)
val theType : Type =rtmMirror.reflect(root).symbol.toType
val methods : Iterable[MethodSymbol]=
theType.declarations.filter(_.isMethod).map(_.asMethod)
val constructorSymbol:MethodSymbol=methods.filter{m=>m.isConstructor && m.paramss.flatten.
isEmpty}.headOption.
getOrElse(throw new RuntimeException("no parameterless constructor in root!") )
val constructorMirror: MethodMirror = classMirror.reflectConstructor(constructorSymbol)
val valueGetters:Iterable[Symbol]=theType.members.filter{
case ms:MethodSymbol=>ms.isGetter && isValueType(ms.returnType)
case _ => false
}
def isValueType(tpe:Type)=
List(typeOf[String],typeOf[AnyVal],typeOf[java.lang.Long]).exists{tpe <:< _}
def getValueCopy= {
val copy= constructorMirror.apply()
val copyR=ReflectionOfEntity(copy)
//valueGetters.foreach()
copy
}
}
【问题讨论】:
标签: scala reflection deep-copy