How can I reflect on a field annotation (Java) in a Scala program?

浪子不回头ぞ 提交于 2021-01-29 14:21:35

问题


I'm using Scala 2.13 and I know there's been a lot deprecated since older versions.

I've got this annotation:

@Inherited
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Foo {
    int index() default 0;
}

(I know... I've got lots of ElementTypes there, but I'm struggling to see where this pops up in reflection so wanted to maximize my chances of a hit!)

Used like this:

case class Person(name: String, @Foo(index = 3) age: Int)
val p = Person("Fred", 29)

How can I reflect on this to get the my Java Annotation (Foo), so I can 1) know whether @Foo exists on a given field, and 2) get the index value. Note I have a declared default value for Foo.index that may be overridden at runtime, so this is a runtime-scoped annotation.


回答1:


Here is solution using Java reflection.

For @(Foo @field)(index = 3) age: Int do

println(classOf[Person].getDeclaredFields.map(_.getDeclaredAnnotationsByType(classOf[Foo]).map(_.index)).deep)
//Array(Array(), Array(3))

For @(Foo @getter)(index = 3) age: Int do

println(classOf[Person].getDeclaredMethods.map(_.getDeclaredAnnotationsByType(classOf[Foo]).map(_.index)).deep)
//Array(Array(), Array(), Array(3), Array(), Array(), Array(), Array(), Array(), Array(), Array(), Array(), Array(), Array())

For @(Foo @param)(index = 3) age: Int or just @Foo(index = 3) age: Int do

println(classOf[Person].getDeclaredConstructors.map(_.getParameters.map(_.getDeclaredAnnotationsByType(classOf[Foo]).map(_.index))).deep)
//Array(Array(Array(), Array(3)))

You can combine meta-annotations @field, @getter, @param.

I guess similar thing can be done with Scala reflection.



来源:https://stackoverflow.com/questions/59620528/how-can-i-reflect-on-a-field-annotation-java-in-a-scala-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!