代码之家  ›  专栏  ›  技术社区  ›  Tom

如何在scala代码中访问scala注释

  •  0
  • Tom  · 技术社区  · 5 年前

    我定义了一个简单的scala注释,并用它来注释我的case类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方法中,annotations数组总是空的,

    0 回复  |  直到 5 年前
        1
  •  2
  •   Dmytro Mitin    5 年前

    首先, 在源代码中可以访问用Scala编写的注释(如果注释扩展 scala.annotation.Annotation )和类文件(如果注释扩展 scala.annotation.StaticAnnotation ). 为了在运行时可以访问,必须用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 ). 他们不应该注释 @说明 但它的应用。

    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,
    
                       @(Description @field)(value = "age00")
                       age: Int,
    
                       @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)
    
    推荐文章