从scala

时间:2017-03-02 21:12:46

标签: java scala reflection

我有以下代码(大部分内容来自另一个SE问题,Scala returns no annotations for a field):

val cls = peripheral.getClass
import scala.reflect.runtime.universe._
val mirror = runtimeMirror(cls.getClassLoader)
val clsSymbol = mirror.staticClass(cls.getCanonicalName)
val decls = clsSymbol.toType.decls.filter(s => s"$s".startsWith("variable "))
for (d <- decls) {
  val classname = classOf[InjectExt].getCanonicalName
  val list = d.annotations.filter(v => v.toString equals classname)
  if (list.nonEmpty) {
    val annotation = list.head
    // what now?
  }
}

其中InjectExt是以下Java注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectExt {
    String id() default "auto";
}

这有效,但现在我得到了这个&#34;注释&#34;只有一个方法:tree()。我该怎么做才能得到我的InjectExt.id()?
而且,toString()的过滤看起来似乎是一种解决方法,但它看起来并不像我可以使用的任何isVariable或类似。

1 个答案:

答案 0 :(得分:2)

使用纯Java反射,您可以轻松获得所需内容。我发现Scala反射过于复杂。

object Test {
  class SomeClass {
    @InjectExt(id = "someCoolId") val myMember = 2
    @InjectExt(id = "someOtherCoolId") val myOtherMember = 2
  }

  def getFieldId(fieldName: String, someInstance: SomeClass): String = {
    val myMember = someInstance.getClass.getDeclaredField(fieldName)
    myMember.getDeclaredAnnotation(classOf[InjectExt]).id()
  }

  def main(args: Array[String]): Unit = {
    println(getFieldId("myMember", new SomeClass))
    println(getFieldId("myOtherMember", new SomeClass))
  }
}

输出:

someCoolId
someOtherCoolId

如果我是你,我会避免使用Scala反射,除非我不能使用Java反射做我想做的事。