【问题标题】:How to access case class field annotation values如何访问案例类字段注释值
【发布时间】:2017-04-28 00:37:12
【问题描述】:

我有一个案例类,我为它的一些字段添加了一些注释:

final class Anno(min: Int, max: Int) extends StaticAnnotation

case class Test(x: String, @Anno(min = 5, max = 10) y: String)

我想迭代案例类的每个字段,获取其值和分配给它的案例类注释属性(如果存在注释)。

知道如何在 Scala 中实现它吗?

【问题讨论】:

  • 你会在这篇文章中找到大部分答案:stackoverflow.com/questions/11468571/…
  • 谢谢。已经看过了。没有太大帮助...返回一个空列表。我已经有一个获取注释列表的解决方案,但没有参考原始案例类参数,而且我不知道一旦我有一个注释类,如何访问注释属性。

标签: scala reflection annotations case-class


【解决方案1】:

要获取case类的构造函数的注解列表,可以使用:

import scala.reflect.runtime.universe._
symbolOf[Test].asClass.primaryConstructor.typeSignature.paramLists.head.map(s => (s -> s.annotations))

但是参数列表中的注解不会自动添加到对应的类成员中。因此,您必须将通过上述调用获得的带注释参数 y 按名称匹配到生成的字段 y

或者,您可以像这样在案例类中注释注释

import scala.annotation.meta._
case class Test(x: String, @(Anno @field)(min = 5, max = 10) y: String)

然后使用

val it = symbolOf[Test].toType.members
  .filter(_.annotations.exists(a => a.tree.tpe <:< typeOf[Anno]))

使用Anno 注释获取可迭代的字段。 对于找到的字段和Test 的实例,您将获得如下值

val yField = it.iterator.next
val o = Test("123", "abc")
universe.runtimeMirror(o.getClass.getClassLoader).reflect(o)
  .reflectField(yField.asTerm).get

【讨论】:

  • 试图用泛型 T 替换 Test 我得到这个异常: scala.ScalaReflectionException: free type T is not a class。有什么办法解决吗?
  • 第一个解决方案似乎可以正确获取注释图。我目前正在迭代案例类并使用以下内容将其转换为字符串:testCaseClass.productIterator.map(_.tostring).mkString("", "|", "")。以我可以访问第一个解决方案的地图的方式迭代案例类的任何方式?
  • 您的帮助将不胜感激。顶级解决方案看起来不错,我基本上有两个问题:1)如何访问注释信息? 2) 如何用通用 T 而不是 Test 编写相同的代码?
  • 如果你用[T : TypeTag]声明你的类型参数,你的方法会得到一个隐式参数,你可以在里面使用typeOf[T]
  • 它编译但返回一个空结果。我尝试类似: def extractAnnotations[T: TypeTag]: Unit = { val allAnnotations = typeOf[T].typeSymbol.asClass.primaryConstructor.typeSignature.paramLists.head.map(.annotations) }。当我将其从方法中取出并直接输入案例类时,它似乎可以工作:typeOf[TestCaseClass].typeSymbol.asClass.primaryConstructor.typeSignature.paramLists.head.map(.annotations)。有什么办法解决吗?
猜你喜欢
  • 2012-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-08
  • 1970-01-01
  • 2022-01-21
相关资源
最近更新 更多