【问题标题】:How to access scala annotation in scala code如何在 scala 代码中访问 scala 注释
【发布时间】:2020-09-24 04:21:49
【问题描述】:

我已经定义了一个简单的 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注解不同于Java注解,你使用Scala Reflection API来访问它们。
  • @LuisMiguelMejíaSuárez。我这里只是用这个简单的代码来说明我的问题,关键是我要使用scala注解,谢谢。
  • @Tom 为什么使用 Scala 注释很重要?你可以使用Java注解吗? (无论如何你使用 Java 反射,而不是 Scala 反射。)
  • @Tom 不管怎样,如果@Description 是 Scala 注释很重要,请查看我使用 Scala 反射的答案的更新。

标签: scala reflection annotations scala-reflect


【解决方案1】:

首先, 用 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)。他们应该注释的不是@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,

                   @(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)

【讨论】:

    猜你喜欢
    • 2021-05-20
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多