java处理注释_如何处理Java注释

java处理注释

Java 8的一项很酷的新功能是对lambda表达式的支持。 Lambda表达式在很大程度上依赖于FunctionalInterface 注释

在本文中,我们将介绍注释以及如何处理它们,以便您可以实现自己的出色功能。

注解

Java 5中添加了注释 。Java语言附带了一些预定义的注释 ,但是您也可以定义自定义注释

许多框架和库都充分利用了自定义注释。 例如, JAX-RS使用它们将POJO转换为REST资源。

注释可以在编译时或在运行时(或什至两者)进行处理。

在运行时,您可以使用反射API 。 可以注释的Java语言的每个元素(如类或方法)都实现AnnotatedElement接口。 请注意,只有具有RUNTIME RetentionPolicy的注释才可以在运行时RUNTIME

编译时注释处理

Java 5附带了单独的apt工具来处理注释,但是自Java 6起,此功能已集成到编译器中。

您可以直接从命令行调用编译器,例如从命令行调用,也可以从程序间接调用。

在前一种情况下,您可以javac指定-processor选项 ,或者通过将文件META-INF/services/javax.annotation.processing.Processor到jar META-INF/services/javax.annotation.processing.Processor来使用ServiceLoader框架。 该文件的内容应为一行,其中包含处理器类的完全限定名称。

ServiceLoader方法在自动构建中特别方便,因为您要做的就是在编译过程中将注释处理器放在类路径上,而MavenGradle之类的构建工具将为您提供帮助。

从应用程序内部进行编译时注释处理

您还可以使用编译时工具从正在运行的应用程序中处理注释。

与其直接调用javac ,不如使用更方便的JavaCompiler接口。 无论哪种方式,您都需要使用JDK而不是JRE运行应用程序。

JavaCompiler接口使您能够以编程方式访问Java编译器。 您可以使用ToolProvider.getSystemJavaCompiler()获得此接口的实现。 此方法对JAVA_HOME环境变量敏感。

JavaCompilergetTask()方法允许您添加注释处理器实例 。 这是控制注释处理器构造的唯一方法。 调用注释处理器的所有其他方法都要求处理器具有公共的无参数构造函数。

注释处理器

处理器必须实现Processor接口。 通常,您将需要扩展AbstractProcessor基类,而不是从头开始实现接口。

每个注释处理器必须通过getSupportedAnnotationTypes()方法指示其感兴趣的注释类型。 您可以返回*以处理所有注释。

另一个重要的事情是指出您支持的Java语言版本。 重写getSupportedSourceVersion()方法并返回RELEASE_x常量之一。

使用这些方法,注释处理器就可以开始工作了。 处理器的作用在process()方法中。

process()返回true ,处理的注释被这个处理器权利 ,并且将不被提供给其它处理器。 通常,您应该与其他处理器配合使用并返回false

元素和类型镜

注释和它们所在的Java元素作为Element对象提供给process()方法。 您可能需要使用Visitor模式处理它们

元素最有趣的类型是用于类和接口(包括注释)的TypeElement ,用于方法的ExecutableElement和用于字段的VariableElement

每个Element指向一个TypeMirror ,它表示Java编程语言中的一种类型。 您可以使用TypeMirror来遍历正在处理的带注释的代码的类关系,就像在JVM中运行的代码上使用反射一样。

加工回合

注释处理发生在称为rounds的单独阶段中。 在每个回合中,处理器都有机会处理其感兴趣的注释。

可通过传递到process()方法中的RoundEnvironment参数获得要处理的注释及其上存在的元素。

如果注释处理器在一轮中生成新的源文件或类文件,则编译器将使这些文件可用于下一轮处理。 这一直持续到不再生成新文件为止。

最后一轮不包含任何输入,因此是释放处理器可能已获取的任何资源的好机会。

初始化和配置处理器

注释处理器使用ProcessingEnvironment 初始化 。 此处理环境使您可以创建新的源文件或类文件

它还以选项的形式提供对配置的访问。 选项是键值对,您可以使用-A option在命令行上提供给javac 。 为此,必须在处理器的getSupportedOptions()方法中返回选项的键。

最后,处理环境提供了一些在处理过程中派上用场的支持例程(例如, 获取元素的JavaDoc获取类型的直接超类型 )。

类路径问题

为了在注释处理过程中获得最准确的信息,您必须确保所有导入的类都在类路径上,因为引用不可用类型的类可能具有不完整的信息或完全缺少信息。

当处理大量带注释的类时,这可能会在Windows系统上导致命令行太大 (> 8K)的问题。 即使使用JavaCompiler接口,它仍会在后台调用javac

Java编译器有一个很好的解决方案:您可以使用包含javac 参数的参数文件 。 然后,在命令行上提供参数文件的名称,并在@之前。

不幸的是, JavaCompiler.getTask()方法不支持参数文件,因此您必须使用基础的run()方法。

请记住, getTask()方法是唯一一种允许您构造注释处理器的方法。 如果必须使用参数文件,则必须使用公共的无参数构造函数。

如果遇到这种情况,并且有多个注释处理器需要共享一个类的单个实例,则无法将该实例传递给构造函数,因此将被迫使用诸如Singleton模式之类的东西。

结论

注释是一项令人兴奋的技术,具有许多有趣的应用程序。 例如,我使用它们将REST API中的资源提取到资源模型中,以进行进一步处理,例如生成文档。

翻译自: https://www.javacodegeeks.com/2015/01/how-to-process-java-annotations.html

java处理注释

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值