我正在尝试将一个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用户......)但我仍然无法访问注释。我做错了什么?
答案 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
}
该参考文献提出了另外两种选择:
将注释的元素类型更改(添加)到(包括)PARAMETER;只有在源可用时才可行。
使用已重命名为target package in 2.9.2的meta package for 2.10将注释重新分类(重新定位)到基础字段(或其他选项)。