【问题标题】:Get case class annotations with reflection?使用反射获取案例类注释?
【发布时间】:2016-12-17 18:40:11
【问题描述】:

我有一个类似的案例类:

case class Foo (@Annotation bar: String)

我希望能够访问该注释及其存储的任何信息

我可以使用 scala 反射(使用 2.11.8)来获取案例访问器

val caseAccessors = 
  universe.typeTag[T].
    tpe.
    decls.
    filter(_.isMethod).
    map(_.asMethod).
    filter(_.isCaseAccessor)

但是当我尝试访问他们的.annotations 时,什么都没有。我意识到注解在技术上是在构造函数参数上,但我该如何得到它呢?

【问题讨论】:

  • 您的注释是否扩展scala.annotation.StaticAnnotation
  • 不,这些是另一个库中的 java 注释,它们具有运行时保留

标签: scala scala-reflect


【解决方案1】:

您的@Annotation 将在构造函数参数和伴随对象apply 方法上,您可以通过名称找到它们。我认为不存在过滤构造函数/主构造函数/伴随对象工厂方法的特定方法。这两个都应该工作:

universe.typeTag[Foo]
  .tpe
  .declarations
  .find(_.name.toString == "<init>")
  .get
  .asMethod
  .paramss
  .flatten
  .flatMap(_.annotations)

universe.typeTag[Foo.type]
  .tpe
  .declarations
  .find(_.name.toString == "apply")
  .get
  .asMethod
  .paramss
  .flatten
  .flatMap(_.annotations)

(虽然我使用的是 Scala 2.11.8 并且没有 decls 但有 declarations

如果您想将注释放在字段或 getter 上,请使用 scala.annotation.meta 包:

import scala.annotation.meta
case class Foo (@(Annotation @meta.getter) bar: String)

在这种情况下,您的代码将起作用(如果您将 typeTag[T] 中的 T 更改为 Foo

查看scala.annotation.meta的文档

【讨论】:

  • 很好,也是唯一对我有用的东西......但是我怎样才能将它与案例类的成员值联系起来?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
  • 2014-02-12
  • 1970-01-01
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多