专栏名称: 开发者全社区
分享和推送Java/Android方向的技术和文章,让你成为这方面的大牛,让你每天都成长一点。同时,我们也会邀请BAT的大牛分享原创!
目录
相关文章推荐
鸿洋  ·  Android系统native进程之我是in ... ·  2 天前  
鸿洋  ·  安卓应用跳转回流的统一和复用 ·  3 天前  
郭霖  ·  Android 跨进程+解耦的数据持久化方案 ·  1 周前  
鸿洋  ·  一个大型 Android 项目的模块划分哲学 ·  1 周前  
51好读  ›  专栏  ›  开发者全社区

编译期注解之APT

开发者全社区  · 公众号  · android  · 2017-01-17 11:47

正文

相关阅读:

如何让你的App永远在后台存活:对Android进程守护、闹钟后台被杀死的研究

Android提升:高工必备技能!

[干货]2017已来,最全面试总结——这些Android面试题你一定需要


概述

 以前的文章介绍了注解的基本知识以及常见用法,由于运行期(RunTime)利用反射去获取信息还是比较损耗性能的,本篇将介绍一种使用注解更加优雅的方式,编译期(Compile time)注解,以及处理编译期注解的手段APT和Javapoet,限于篇幅,本篇着重介绍APT 

首先你的注解需要声明为CLASS 
@Retention(RetentionPolicy.CLASS)

编译期解析注解基本原理: 

在某些代码元素上(如类型、函数、字段等)添加注解,在编译时编译器会检查AbstractProcessor的子类,并且调用该类型的process函数,然后将添加了注解的所有元素都传递到process函数中,使得开发人员可以在编译器进行相应的处理,例如,根据注解生成新的Java类,这也就是ButterKnife等开源库的基本原理。

APT

在处理编译器注解的第一个手段就是APT(Annotation Processor Tool),即注解处理器。在java5的时候已经存在,但是java6开始的时候才有可用的API,最近才随着butterknife这些库流行起来。本章将阐述什么是注解处理器,以及如何使用这个强大的工具。

什么是APT

APT是一种处理注解的工具,确切的说它是javac的一个工具,它用来在编译时扫描和处理注解,一个注解的注解处理器,以java代码(或者编译过的字节码)作为输入,生成.java文件作为输出,核心是交给自己定义的处理器去处理,

如何使用

每个自定义的处理器都要继承虚处理器,实现其关键的几个方法


下面重点介绍下这几个函数:

  1. init(ProcessingEnvironment env): 每一个注解处理器类都必须有一个空的构造函数。然而,这里有一个特殊的init()方法,它会被注解处理工具调用,并输入ProcessingEnviroment参数。ProcessingEnviroment提供很多有用的工具类Elements, Types和Filer

  2. process(Set extends TypeElement> annotations, RoundEnvironment env): 这相当于每个处理器的主函数main()。你在这里写你的扫描、评估和处理注解的代码,以及生成Java文件。输入参数RoundEnviroment,可以让你查询出包含特定注解的被注解元素。这是一个布尔值,表明注解是否已经被处理器处理完成,官方原文whether or not the set of annotations are claimed by this processor,通常在处理出现异常直接返回false、处理完成返回true。

  3. getSupportedAnnotationTypes(): 必须要实现;用来表示这个注解处理器是注册给哪个注解的。返回值是一个字符串的集合,包含本处理器想要处理的注解类型的合法全称。

  4. getSupportedSourceVersion(): 用来指定你使用的Java版本。通常这里返回SourceVersion.latestSupported(),你也可以使用SourceVersion_RELEASE_6、7、8

由于处理器是javac的工具,因此我们必须将我们自己的处理器注册到javac中,在以前我们需要提供一个.jar文件,打包你的注解处理器到此文件中,并在在你的jar中,需要打包一个特定的文件 javax.annotation.processing.Processor到META-INF/services路径下 
把MyProcessor.jar放到你的builpath中,javac会自动检查和读取javax.annotation.processing.Processor中的内容,并且注册MyProcessor作为注解处理器。

超级麻烦有木有,不过不要慌,谷歌baba给我们开发了AutoService注解,你只需要引入这个依赖,然后在你的解释器第一行加上

@AutoService(Processor.class)

然后就可以自动生成META-INF/services/javax.annotation.processing.Processor文件的。省去了打jar包这些繁琐的步骤。

APT中的Elements和TypeMirrors

在前面的init()中我们可以获取如下引用

在注解处理过程中,我们扫面所有的Java源文件。源文件的每一个部分都是一个特定类型的Element

先来看一下Element

对于编译器来说 代码中的元素结构是基本不变的,如,组成代码的基本元素包括包、类、函数、字段、变量的等,JDK为这些元素定义了一个基类也就是Element

Element有五个直接子类,分别代表一种特定类型


| ExecutableElement | 表示某个类或接口的方法、构造方法或初始化程序(静态或实例),包括注解类型元素 |

开发中Element可根据实际情况强转为以上5种中的一种,它们都带有各自独有的方法,如下所示

package com.example;    // PackageElement
public class Test {      
 // TypeElement    
 private int a;      
 // VariableElement    
 private Test other;  
 // VariableElement    
 public Test () {}    
 // ExecuteableElement    
 public void setA (  
 // ExecuteableElement    
           int newA  
           // TypeElement                    
     
     )
     {}
  }


相关阅读

注解基础

APT

JavaPoet

原文:http://blog.csdn.net/xsf50717


Java和Android大牛频道

欢迎关注我们,一起讨论技术,扫描和长按下方的二维码可快速关注我们。搜索微信公众号:JANiubility。

公众号:JANiubility