如何解决如何在Scala代码中访问Scala批注
我已经定义了一个简单的scala注释,并使用它来注释我的案例类Person:
package com.my
import scala.annotation.StaticAnnotation
@scala.annotation.meta.field
class Description(value: String) extends StaticAnnotation{
}
然后在我的Person类中使用它:
package com.my
import scala.beans.BeanProperty
case class Person(
@Description(value = "name00")
name: String,@Description(value = "age00")
age: Int,@BeanProperty
xyz: String = "xyz"
)
object Person {
def main(args: Array[String]): Unit = {
val p = Person("abc",21)
classOf[Person].getDeclaredFields.foreach {
field =>
field.setAccessible(true)
val name = field.getName
val value = field.get(p)
//annotations always return empty array
val annotations = field.getDeclaredAnnotations
annotations.foreach {
annotation =>
val tpe = annotation.annotationType()
println(tpe)
}
println(s"name is $name,value is: $value")
}
}
}
在Person对象的main方法中,注释数组始终为空, 我想问一下如何获取在字段上定义的注释信息。
解决方法
首先,可以在源文件中(如果注释扩展了scala.annotation.Annotation
和类文件(如果注释扩展了scala.annotation.StaticAnnotation
)访问用Scala编写的注释。为了在运行时可访问,注释必须用Java编写
import java.lang.annotation.*;
@Target({ElementType.PARAMETER,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Description {
String value();
}
How to use Scala annotations in Java code
Why annotations written in Scala are not accessible at runtime?
https://www.reddit.com/r/scala/comments/81qzs2/how_to_write_annotations_in_scala/
或者,您可以使用原始的@Description
(用Scala编写并扩展StaticAnnotation
),但是随后您必须在运行时通过Scala reflection而不是Java反射来访问它。
其次,您滥用了元注释(@scala.annotation.meta.field
)。它们不应注释@Description
的定义,而应注释其应用。
import scala.annotation.meta.field
case class Person(
@(Description @field)(value = "name00")
name: String,@(Description @field)(value = "age00")
age: Int,@BeanProperty
xyz: String = "xyz"
)
Annotating case class parameters
How can I reflect on a field annotation (Java) in a Scala program?
Calling a method from Annotation using reflection
输出:
interface Description // appears
name is name,value is: abc
interface Description // appears
name is age,value is: 21
name is xyz,value is: xyz
借助Scala反射,您可以做到
import scala.annotation.StaticAnnotation
import scala.beans.BeanProperty
import scala.annotation.meta.field
import scala.reflect.runtime.universe._
class Description(value: String) extends StaticAnnotation
case class Person(
@(Description @field)(value = "name00")
name: String,@BeanProperty
xyz: String = "xyz"
)
def main(args: Array[String]): Unit = {
val p = Person("abc",21)
typeOf[Person].decls
.collect { case t: TermSymbol if t.isVal => t.annotations }
.foreach(println)
}
//List(Description @scala.annotation.meta.field("name00"))
//List(Description @scala.annotation.meta.field("age00"))
//List(scala.beans.BeanProperty)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。