一.注解
* 什么是注解
注解是代码里面的特殊标记,这些标记可以在编译、类加载、运行时被读取。JDK5开始出现注解
注解分为标准注解和元注解
标准注解是 JDK 自带的注解
@Override[SOURCE/METHOD],@Deprecated[RUNTIME,7个],@SuppressWarnings[SOURCE,6个
],@SafeVarargs[JDK7,RUNTIME/CONSTRUCTOR/METHOD]
元注解是用来注解其他注解的注解--自定义注解
@Target
注解所修饰的对象范围[TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE]
@Inherited 表示注解可以被继承
@Documented 表示这个注解应该被 JavaDoc 工具记录
@Retention 用来声明注解的保留策略[SOURCE,CLASS,RUNTIME]
@Repeatable[JDK8] 允许一个注解在同一个声明类型(类、属性或者方法)上多次使用
* 定义注解
定义注解使用 @interface 关键字
使用注解
* 注解处理器
运行时注解处理器--反射,Demo
编译时注解处理器--APT,承上启下
二.APT
* 什么是APT
APT即为Annotation Processing
Tool,它是javac的一个工具。APT可以用来在编译时扫描和处理注解。通过APT可以获取到注解和被注解对象的相关信息,在拿到这些信息后我们可以根据需求来自动的生成一些代码,省去了手动编写。注意,获取注解及生成代码都是在代码编译时候完成的,相比反射在运行时处理注解大大提高了程序性能。
应用范围:
Lombok,Databinding,Dragger2,EventBus3,ARouter等等
* APT工作流程
* 定义APT
3.1 AbstractProcessor介绍
Java/Android中,APT主要以继承AbstractProcessor在编译是处理注解的。
AbstractProcessor在JDK6才出来,抽象类
关键方法/引用:
init(ProcessingEnvironment
processingEnv):初始化,processingEnv可以获取到Filer/Messager/一些工具类
Set<String> getSupportedAnnotationTypes():需要处理的注解集合
boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
roundEnv):处理注解,true当前process处理,false不处理,交
给后面的process处理,roundEnv获取源码上注解的Element信息
3.2 Element介绍
Element是一个接口,表示一个程序元素,它可以指代包、类、方法或者一个变量。
PackageElement 表示一个包程序元素。提供对有关包及其成员的信息的访问。
ExecutableElement 表示某个类或接口的方法、构造方法或初始化程序(静态或实例),包括注释类型元素。
TypeElement 表示一个类或接口程序元素。提供对有关类型及其成员的信息的访问。注意,枚举类型是一种类,而注解类型是一种接口。
VariableElement 表示一个字段、enum 常量、方法或构造方法参数、局部变量或异常参数。
把Java文件看成一个字符串(类似JSON/XML)来理解Element。
* 使用APT
4.1 创建注解库
创建一个Java Library,根据目的定义注解,定义好注解类
4.2 创建处理器库
创建一个Java Library,同时创建一个Processor类,JavaBenProcess,继承AbstractProcessor。
4.3 注册处理器
a.通过AutoService自动注册,注意要同时annotationProcess和implemention
b.通过手动添加meta-info信息注册
4.4 实现注解处理
a. 生成新的Java文件
通过JavaPoet/JavaWriter/StringBuffer生成Java文件
b. 修改原来的Java文件
修改AST
4.5 使用注解
a. annotationProcess处理器的module
b. implemention 注解module
c. 在类上添加注解
d. build一下工程
e. 在使用处调用生成的方法
5.调试APT
5.1采用debug方式
5.2采用日志+ gradlew clean;gradlew :app:compileDebugJavaWithJavac
三. AST
* 什么是AST
抽象语法树(Abstract Syntax Tree,
AST)是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的结构,树的每个节点ASTNode都表示源码中的一个结构。AST把java中的各种元素比如类、属性、方法、代码块、注解、注释等等定义成相应的对象,在编译器编译代码的过程中,语法分析器首先通过AST将源码分析成一个语法树,然后再转换成二进制文件。
* AST在编译器的位置