访问Scala中的注释值
发布时间:2020-12-16 09:00:51 所属栏目:安全 来源:网络整理
导读:TL; DR:基本上,我正在寻找 Java的Scala等价物: (MyAnnotation) Thing.getClass().getAnnotations()[0] 尽管我可以愉快地发现基于其类型的注释和查询,但我似乎无法从scala.reflect.runtime.universe.Annotation获取到我的实际类型. scala // Declare an ann
TL; DR:基本上,我正在寻找
Java的Scala等价物:
(MyAnnotation) Thing.getClass().getAnnotations()[0] 尽管我可以愉快地发现基于其类型的注释和查询,但我似乎无法从scala.reflect.runtime.universe.Annotation获取到我的实际类型. scala> // Declare an annotation (it seems StaticAnnotation means runtime scala> // retention) scala> case class MyAnnotation(x: Int,y: String) extends scala.annotation.StaticAnnotation defined class MyAnnotation scala> // Make a thing decorated with MyAnnotation scala> @MyAnnotation(x=5,y="cool") case class Thing() defined class Thing scala> // Look at the annotation on the Thing...the runtime clearly scala> // understands the values on it scala> val annotation = scala.reflect.runtime.universe.typeOf[Thing].typeSymbol.asClass.annotations(0) annotation: reflect.runtime.universe.Annotation = MyAnnotation(5,"cool") scala> // I can sort of get at the values by index,which isn't terribly scala> // safe scala> annotation.scalaArgs(0) res0: reflect.runtime.universe.Tree = 5 scala> // And what is a Tree here anyway? It certainly isn't a String (or scala> // Int). I just want the value! scala> annotation.scalaArgs(1) res1: reflect.runtime.universe.Tree = "cool" scala> // But how do I get at those values programatically? scala> annotation.asInstanceOf[MyAnnotation] java.lang.ClassCastException: scala.reflect.internal.AnnotationInfos$CompleteAnnotationInfo cannot be cast to MyAnnotation at .<init>(<console>:13) at .<clinit>(<console>) at .<init>(<console>:7) at .<clinit>(<console>) at $print(<console>) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:734) at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:983) at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:573) at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:604) at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:568) at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:760) at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:805) at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:717) at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:581) at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:588) at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:591) at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:882) at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:837) at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:837) at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135) at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:837) at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:83) at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96) at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105) at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala) 关于这一切的欢乐部分是我甚至不能使用传统的Java方法,因为Scala不再费心从getAnnotations()填充数组了. scala> Thing.getClass.getAnnotations.length res2: Int = 0 有关 我认为我想要的是在“Reflection Overview”的“在运行时实例化类型”一节中,但我不明白为什么我必须跳过这么多的箍只是为了获得注释中的值.在Java中,价值只是一个抛弃. 问题“See annotations in Scala reflection”似乎有关,但问题是从2011年开始,适用于Scala 2.9.我正在使用2.10,据我所知,从那时起,大量的反射工作方式发生了变化. 解决方法
不是java等价物,但是使用scala 2.11.6,这可以从注释中提取值:
case class MyAnnotationClass(id: String) extends scala.annotation.StaticAnnotation val myAnnotatedClass: ClassSymbol = u.runtimeMirror(Thread.currentThread().getContextClassLoader).staticClass("MyAnnotatedClass") val annotation: Option[Annotation] = myAnnotatedClass.annotations.find(_.tree.tpe =:= u.typeOf[MyAnnotationClass]) val result = annotation.flatMap { a => a.tree.children.tail.collect({ case Literal(Constant(id: String)) => DoSomething(id) }).headOption } 我知道你可能已经做过了,但以防万一它可以帮助别人:) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |