如何处理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方法在自动构建中特别方便,因为您要做的就是在编译过程中将注释处理器放在类路径上,而Maven或Gradle之类的构建工具将为您提供帮助。

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

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

与其直接调用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361206.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(转)MFC技巧学习五

51. 如何获得其他程序的图标,并显示在View中 [问题提出] 有的时候,如:类资源管理器会遇到获得程序图标并显示的操作,如何实现呢? [解决方法] SDK函数SHGetFileInfo来获得有关文件的很多信息:如大小图标,属性,类型等.  [程序实现] 建立名为My的SDI工程.在OnPaint()函数中…

使用navicat premium将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL

有时候我们有迁移数据库的需求,例如从Oracle迁移到SQL Server,或者从MySQL迁移到Oracle。 很多江湖好汉一时不知如何手工操作,所幸的是Navicat提供了迁移的自动化操作界面。 当然,Navicat的数据库迁移无法做到完美,一些…

书评:Mockito Essentials

Sujoy Acharya的Mockito Essentials副标题( Packt Publishing ,2014年10月)是:“实用指南,可帮助您使用Mockito进行单元测试并开始运行。” Mockito Essentials中的前言和七章涵盖大约190个实质性页面。 前言 在序言中…

Oracle ORA-07445 [evaopn3()+384] 错误 分析

1.OS 和 DB 版本Oracle Version: 11.2.0.2Operation System:HP-UXItanium 11.312.Alert log中信息Tue Oct 16 22:27:31 2012Exception [type: SIGSEGV,Address not mapped to object] [ADDR:0xC00000000] [PC:0x400000000631B880,evaopn3()384] [flags: …

http网站转换成https网站

https,https的本地测试环境搭建,asp.net结合https的代码实现,http网站转换成https网站之后遇到的问题 一:什么是https SSL(Security Socket Layer)全称是加密套接字协议层,它位于HTTP协议层和TCP协议层之间&#x…

EAGER的获取是代码的味道

介绍 休眠获取策略确实可以使几乎没有爬网的应用程序和响应速度很快的应用程序有所不同。 在这篇文章中,我将解释为什么您应该选择基于查询的获取而不是全局获取计划。 取得101 Hibernate定义了四种关联检索策略 : 提取策略 描述 加入 原始SELECT语…

基于S2SH的电子商务网站系统性能优化

对于经常逛网页的人来说最受不了的事情就是访问的网页加载太慢,除去网络的原因网站的系统性能对加载的快慢非常重要, 网上有个统计: 每慢500ms Google访问量降低20% 每慢400ms Yahoo 访问量降低5-9% 每慢100ms Amazon销售额降低1% 对于商务网…

玩Java并发

最近,我需要将一些文件(每个文件都有JSON格式的对象列表(数组))转换为每个文件都具有相同数据(对象)的分隔行的文件。 这是一次性的任务,很简单。 我使用Java nio的某些功能进行了读…

ExtJs的Reader

ExtJs的Reader Reader : 主要用于将proxy数据代理读取的数据按照不同的规则进行解析,讲解析好的数据保存到Modle中 结构图 Ext.data.reader.Reader 读取器的根类 Ext.data.reader.Json JSON格式的读取器 Ext.data.reader.Array 扩展JSON的Array读取器 Ext.data.reader.Xml XML格…

sound

sound类在 flash3.0中算是很常见的功能,也是很常用的,下面 简单的运用了 sound类,加载了一首歌,控制 播放 暂停 停止,和控制音量大小; package {import flash.display.MovieClip;import fl.controls.*;imp…

Java Lambdas和低延迟

总览 有关在Java和低延迟中使用Lambda的主要问题是: 它们会产生垃圾吗,您能做些什么吗? 背景 我正在开发一个支持不同有线协议的库。 这样的想法是,您可以描述要写入/读取的数据,并且有线协议确定它是否使用带有JSon或…

HTTP协议/RTSP协议/RTMP协议的区别

RTSP、 RTMP、HTTP的共同点、区别 共同点: 1:RTSP RTMP HTTP都是在应用应用层。 2: 理论上RTSP RTMP HTTP都可以做直播和点播,但一般做直播用RTSP RTMP,做点播用HTTP。做视频会议的时候原来用SIP协议,现…

2013搜狗校园招聘笔试题

研习了Linux公社发布的2013搜狗校园招聘笔试题,还是有些收获的。 //第一题:以下程序的输出是___________________ class Base { public:Base(int j):i(j){}virtual ~Base(){}void func1(){i * 10; func2();}int getValue(){return i;} protected:virtual…

Java中的线程本地存储

开发人员中鲜为人知的功能之一是线程本地存储。 这个想法很简单,并且在需要数据的情况下很有用。 如果我们有两个线程,则它们引用相同的全局变量,但我们希望它们具有彼此独立初始化的单独值。 大多数主要的编程语言都有该概念的实现。 例如&…

jsp中@import导入外部样式表与link链入外部样式表的区别

昨天碰到同事问了一个问题,impor导入外部样式与link链入外部样式的优先级是怎样的,为什么实验的结果是按照样式表导入后的位置来决定优先级。今天就这个问题具体总结如下: 先解释一下网页添加css样式的方法,一共有四种&#xff0c…

EBS调试

一、在请求中的调试: 1、用系统函数fnd_file.PUT_LINE(),然后在请求的查看日志中就可以看到 例如: fnd_file.PUT_LINE(fnd_file.log, l_customer_type); 其中l_customer_type就是要查看的变量。 2、先建一张表,然后在程序中执行…

Acision推出“ forgeathon” –第一个WebRTC应用挑战

Acision推出了“ forgeathon”,这是 面向全球开发人员的 首个在线丰富网络通信(WebRTC)应用挑战 加入Forgeathon,让Acision帮助您将应用程序或服务推向全球! 英国雷丁– 2015年1月6 日 :安全,…

SQL Server 中的ROWID

在SQL Server中没有像Orcal中的rowid,但是可以运用一定的变通达到这个效果。1、建立临时表,其中包含rowid,2、重命名原表后删除临时表USE TianzxSELECT identity(int,1,1) as rowid,flow.* into temptable from flow--建立临时表,…

jsp中四种传递参数的方法

jsp中四种传递参数的方法如下&#xff1a; 1、form表单 2、request.setAttribute();和request.getAttribute(); 3、超链接&#xff1a;<a herf"index.jsp"?aa&bb&cc>name</a> 4、<jsp:param> 下面一一举例说明&#xff1a; 1、form表…

多个退货单

我曾经听说过&#xff0c;过去人们为使方法具有单个出口点而奋斗。 我知道这是一种过时的方法&#xff0c;从未认为它特别值得注意。 但是最近&#xff0c;我与一些仍坚持该想法的开发人员进行了联系&#xff08;最后一次是在这里 &#xff09;&#xff0c;这让我开始思考。 因…