使用反射从注解调用方法 [英] Calling a method from Annotation using reflection

查看:63
本文介绍了使用反射从注解调用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有带有 Size 注释的 Sample

I have Sample class with Size annotation

case class Sample(
  attr: SomeTypeA
  @Size(value = 50)
  name: SomeTypeB)

这个Size注解是一个实现AnnotationInterface

trait AnnotationInterface[T] {
  def getValue: T
}

class Size(value: Int) extends StaticAnnotation with AnnotationInterface[Int] {
    override def getValue: Int = value
}

我有 Extractor 负责使用反射提取类成员

And I have Extractor which is responsible for extracting class members using reflection

class Extractor[A](implicit
    tt: TypeTag[A],
    ct: ClassTag[A]
) { ...extract class members using reflection... } 

然后我会像这样实例化提取器:

Then I would instantiate the extractor like:

val extractor: Extractor[Sample] =
      new Extractor 

问题:如何在 Extractor 类中调用方法 getValue: T ?

Question : How can I call the method getValue: T inside the class Extractor ?

推荐答案

如果你像这样注释

@Size(50) name: String

而不是像

@(Size @getter @setter @field)(50) name: String

then @Size 仅保留在构造函数参数上,而不是字段、getter 或 setter.所以你需要使用A的构造函数.

then @Size remains only on constructor parameter, not field, getter or setter. So you need to use constructor of A.

试试

class Extractor[A](implicit
                   tt: TypeTag[A],
                   ct: ClassTag[A]
                  ) {
  val annotationTree = typeOf[A]
    .decl(termNames.CONSTRUCTOR).asMethod
    .paramLists.flatten
    .flatMap(_.annotations)
    .map(_.tree)
    .filter(_.tpe =:= typeOf[Size])
    .head 

  annotationTree match {
    case q"new $_($value)" => println(value) //50
  }
}

如果您需要value

import scala.tools.reflect.ToolBox
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()

tb.eval(tb.untypecheck(annotationTree)).asInstanceOf[Size].getValue //50

如果你真的想调用 getValue.

顺便说一下,如果您可以访问 Size 并且可以将其设置为 case 类(或 case-class-like),那么您可以在大多数情况下执行相同的操作编译时间

By the way, if you have access to Size and can make it a case class (or case-class-like) then you can do the same mostly at compile time

import shapeless.Annotations

Annotations[Size, Sample].apply() // None :: Some(Size(50)) :: HNil

这篇关于使用反射从注解调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆