Scala:通过反射从单个对象中提取注释

时间:2017-03-09 20:29:54

标签: scala reflection annotations

如何在给定字符串的情况下访问单个对象的注释?

我正在使用Scala版本2.11.6并计划在将此问题排除后升级到2.12。

实施例

给定(java)注释

public @interface Marked {
  String name();
}

和简化的工厂界面

trait Instance { def doSomething(): Unit }
trait Factory { def create(): Instance }

我想检查一个动态加载的单例对象是否被注释并具有什么值。单例对象将放在类路径中,可以这样定义:

class A extends Instance { override def doSomething() { println("A is done.") } }

@Marked(name = "My A Factory")
object AFactory extends Factory {
  override def create(): Instance = new A()
}

我尝试了什么

我只能动态访问模块(单例对象),这样就无法访问注释。主要是由于缺乏全面的文档,我尝试了以下表达式,它们都以某种方式返回一个空列表。

import scala.reflect.runtime.{universe => ru}
val name = "AFactory$" // This is automatically provided.
val rm = ru.runtimeMirror(getClass.getClassLoader)

val classSym = rm.staticClass(name)
println(classSym.annotations)
println(classSym.companion.annotations)
println(classSym.baseClasses(0).annotations)
println(classSym.baseClasses(0).companion.annotations)

val moduleSym = rm.staticModule(name)
println(moduleSym.companion.annotations)
println(moduleSym.asModule.annotations)
println(moduleSym.asModule.moduleClass.annotations)
println(moduleSym.asModule.moduleClass.companion.annotations)

1 个答案:

答案 0 :(得分:1)

您需要在运行时使JVM保留注释,否则它将不起作用=>

@Retention(RetentionPolicy.RUNTIME)
public @interface Marked {
}

通过此更改,您的代码可以正常运行。 编辑: 原因是,默认保留是" Class",这将使编译器在类文件中保留注释,但在运行时它不可访问。