Scala类字段上的getAnnotations

时间:2012-08-07 20:46:56

标签: java scala reflection

我正在尝试将一个Java库(JOhm)与Scala一起使用,并注意到当lib尝试使用类似field.isAnnotationPresent(Id.class)的内容读取Scala类字段上的注释时,它会失败。

注释在Java中定义为:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Id {

}

因此它们应该在运行时可用。但是,如果我尝试:

scala> import redis.clients.johm._
import redis.clients.johm._

scala> class myClass(@Id var id: java.lang.Long)
defined class myClass

scala> new myClass(id = null)
res0: myClass = myClass@5157cfbc

scala> res0.getClass.getDeclaredFields
res1: Array[java.lang.reflect.Field] = Array(private java.lang.Long myClass.id)

scala> res0.getClass.getDeclaredFields.map(_.getAnnotations)
res2: Array[Array[java.lang.annotation.Annotation]] = Array(Array())

然后我设法获取字段(感谢StackOverflow用户......)但我仍然无法访问注释。我做错了什么?

1 个答案:

答案 0 :(得分:4)

感谢reference provided的'soc',有一个明确的答案:“默认情况下,(val-,var-或plain)构造函数参数上的注释最终会出现在参数...”。

有问题的注释是针对具有运行时保留的FIELD元素定义的,而它是应用于scala构造函数参数(PARAMETER)。

我最近尝试在scala构造函数“var”参数上使用JAXB FIELD级别@XmlElement注释时遇到了同样的情况 - 对我来说也不起作用。

我通过在类中定义一个distinct字段并从构造函数的参数列表中初始化它来解决了我的JAXB问题(消除了'val / var'关键字)。在你的情况下可能看起来像:

class myClass(_id: java.lang.Long) {
    @Id var id = _id
}

该参考文献提出了另外两种选择:

  1. 将注释的元素类型更改(添加)到(包括)PARAMETER;只有在源可用时才可行。

  2. 使用已重命名为target package in 2.9.2meta package for 2.10将注释重新分类(重新定位)到基础字段(或其他选项)。