简短版本: 给定一个getter符号我想找到相应的setter符号。
长版:
下面是Scala Reflection的一个小实用程序类。
我计划使用这个类深层复制Hibernate Entities(抽象类UUIDEntity
的子类)。
我将深拷贝分成两部分,1)对象图中的每个对象进行值复制2)连接隔离的拷贝以形成克隆的对象图。这个问题只涉及第一部分。
让root
成为实体。
首先,我想创建root
的值副本,让我们称之为copy
。值复制意味着我只填写副本中的值字段(请参阅下面的值字段的定义)。
这应该在getValueCopy
方法中进行。
有val copy
,但在使用val copy= constructorMirror.apply()
所以我需要将root
中的字段复制到copy
。为此,我需要获取字段的setter和getter(更准确地说,值字段是引用值类,如Int,String,Long等的字段)。
到目前为止,我设法找到了值字段的getter(valueGetters
),但是,我的问题是我想找到相应的setter。但我真的不知道什么是将安装者与吸气剂配对的最佳方式?
使用方法名称是唯一的方法吗?这就是我天真的做法,但我的感觉告诉我必须有更好的方法。
欢迎任何建议。谢谢你的阅读。
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
}
}
答案 0 :(得分:1)
MethodSymbol
为字段提供isCaseAccessor
,isGetter
,isSetter
,accessed
,为设置者提供setter
。
如果需要代码,我可以使用这种做法,但可能不是。
我是否在寻找与您不同的ScalaDoc?有时候很难知道在哪里看。
编辑:实际上它位于TermSymbolApi
。
更新
scala> class C(var i: Int, var s: String)
defined class C
scala> typeOf[C].declarations.filter(s => s.isMethod && s.asMethod.isGetter && s.asMethod.setter != NoSymbol)
res10: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(method i, method s)
scala> .map { s => val m = s.asMethod ; (m, m.setter) }
res11: Iterable[(reflect.runtime.universe.MethodSymbol, reflect.runtime.universe.Symbol)] = List((method i,method i_=), (method s,method s_=))