How to list all fields with a custom annotation using Scala's reflection at runtime?

你。 提交于 2019-11-30 17:00:15

问题


I have a custom annotation like

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

For a given class, how can I list all its fields that have this annotation? I'm looking for something like (just guessing):

def listProperties[T: ClassTag]: List[(SomeClassRepresentingFields,MyProperty)];

回答1:


This can be done with a TypeTag, by filtering through the members of your input type:

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
}

Then:

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("")))

This doesn't give you directly a MyProperty but a universe.Annotation. It has a scalaArgs method that gives you access to its arguments as trees if you need to do something with then.



来源:https://stackoverflow.com/questions/17792383/how-to-list-all-fields-with-a-custom-annotation-using-scalas-reflection-at-runt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!