如何在运行时使用Scala的反射列出带有自定义注释的所有字段?

6

我有一个自定义注释,例如:

class MyProperty(val name: String)
  extends annotation.StaticAnnotation; // or should I extend something else?

对于给定的类,如何列出所有具有此注释的字段?我需要像这样的东西(只是猜测):
def listProperties[T: ClassTag]: List[(SomeClassRepresentingFields,MyProperty)];
1个回答

12
这可以通过使用TypeTag,并筛选您输入类型的members来实现:
import reflect.runtime.universe._

def listProperties[T: TypeTag]: List[(TermSymbol, Annotation)] = {
  // a field is a Term that is a Var or a Val
  val fields = typeOf[T].members.collect{ case s: TermSymbol => s }.
    filter(s => s.isVal || s.isVar)

  // then only keep the ones with a MyProperty annotation
  fields.flatMap(f => f.annotations.find(_.tpe =:= typeOf[MyProperty]).
    map((f, _))).toList
}

然后:

scala> class A { @MyProperty("") val a = 1 ; @MyProperty("a") var b = 2 ; 
  var c: Long = 1L }
defined class A

scala> listProperties[A]
res15: List[(reflect.runtime.universe.TermSymbol, reflect.runtime.universe.Annotation)]
  = List((variable b,MyProperty("a")), (value a,MyProperty("")))

这并没有直接给你一个MyProperty,而是一个universe.Annotation。它有一个scalaArgs方法,如果需要对其参数执行某些操作,则可以访问其参数作为树形结构。


1
我在普通类中工作得很好,但在带有自定义注释字段的案例类中不起作用。你能帮我调整一下吗? - Chiheb.K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接