我希望通过反射得到注释实例,我尝试使用此方法link但它不起作用。
当注释字段类型是基本且没有默认值时会成功,但是当类型很复杂或具有默认值时,它将失败。
在我的代码中:
import org.scalatest.FunSuite
import scala.annotation.StaticAnnotation
import scala.reflect.runtime.universe._
object ReflectHelper {
val runtime = runtimeMirror(getClass.getClassLoader)
/**
* @param beanClazz target bean class
* @tparam A target annotation
* @return annotation instances
*/
def getClassAnnotation[A: TypeTag](beanClazz: Class[_]): Option[A] = {
val typeAnnotation = typeOf[A]
scala.reflect.runtime.currentMirror.classSymbol(beanClazz).toType.typeSymbol.asClass.annotations.find(a => a.tree.tpe == typeAnnotation).map {
annotation =>
/*
* Has error : scala.reflect.internal.Trees$Select cannot be cast to scala.reflect.api.Constants$ConstantApi
* when annotation field use default value
*
* Has error : scala.reflect.internal.Trees$TypeApply cannot be cast to scala.reflect.api.Constants$ConstantApi
* when annotation field type is collection
*/
val value = annotation.tree.children.tail.map(_.productElement(0).asInstanceOf[Constant].value)
runtime.reflectClass(typeAnnotation.typeSymbol.asClass).
reflectConstructor(typeAnnotation.decl(termNames.CONSTRUCTOR).asMethod)(value: _*).
asInstanceOf[A]
}
}
}
case class Entity1(idField: String = "id") extends StaticAnnotation
case class Entity2(rels: List[String] = List()) extends StaticAnnotation
@Entity1(idField = "pk")
case class Test1Entity()
@Entity1()
case class Test2Entity()
@Entity2(rels = List("fieldA"))
case class Test3Entity()
class Test extends FunSuite {
test("Bean Test") {
//Success
assert(ReflectHelper.getClassAnnotation[Entity1](classOf[Test1Entity]).get.idField == "pk")
//Error : scala.reflect.internal.Trees$Select cannot be cast to scala.reflect.api.Constants$ConstantApi
assert(ReflectHelper.getClassAnnotation[Entity1](classOf[Test2Entity]).get.idField == "id")
//Error : scala.reflect.internal.Trees$TypeApply cannot be cast to scala.reflect.api.Constants$ConstantApi
assert(ReflectHelper.getClassAnnotation[Entity2](classOf[Test3Entity]).get.rels(0) == "fieldA")
}
}
感谢。