1. 概念(什么叫注解Annatation)?
2. Java中的常见注解
(1) @Override @Target(ElementType.METHOD)
用于重写父类方法,或者实现接口对应的方法
(2) @ Deprecated
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE,PARAMETER, TYPE})
用于申明函数,变量,类等过时,后续的版本中可能会被删除,不推荐使用,申明了该注解的对象会被打上破折号
(3) @SuppressWarnings 注解元素上的编译器警告应该被压制. 在类上的压制会同样作用到类的方法上.
3. 第三方注解
4. 注解类别
注解分为三类:
(1) 源码注解 @Retention(RetentionPolicy.SOURCE)
编译器编译阶段丢弃该注解
(2) 编译注解 @Retention(RetentionPolicy. CLASS)
Class文件还存在该注解,虚拟机运行时丢弃该注解
(3) 运行时注解 @Retention(RetentionPolicy.RUNTIME)
编译器,虚拟机都会保留该注解,可以通过反射读取注解信息
这几个取值与Retention元类型一起使用确定注解的保留时长.
当注解未定义Retention值时,默认值是CLASS
5. 分类
三种标准注解:@Override、@Deprecated、@SuppressWarnings
四种元注解:@Target、@Retention、@Documented、@Inherited
元注解的Retention取值都是@Retention(RetentionPolicy.RUNTIME)
@Target 指明该注解作用在什么元素上,比如 类/方法/构造函数/成员变量/局部变量/注解/包/参数等 ElementType.java
@Inherited:此注解是标识性的元注解,表示当前注解可以由子注解来继承。
@Documented:表示生成javadoc的时候会包含注解
6. 自定义注解,注解的参数
如果在annotations中只有唯一一个成员,则该成员应命名为value:
所有的自定义Annotation都实现了Annotation接口.
//注解的信息获取 (注解的API+反射API)
7. 注解有什么作用,能用来做什么?
8.各个注解的作用?
SOURCE阶段注解的作用
CLASS阶段注解的作用
RUNTIME阶段注解的作用 ==== 通过反射获取RUNTIME注解的信息
9.注解的案例:
Javabean 与 数据库表的 字段通过注解进行映射
后台在真正处理User表相关的SQL查询时,可以通过注解+反射方式去校验字段,获取字段的name和value, 进行SQL的拼装.
比如javabean类的注解的名字就是要查询的表的名字;
通过Field字段的name以及getXXX来查询字段的name和value。
10. annotation processing tool(APT) –处理编译器注解
APT在代码编译期解析注解,并且生成新的 Java 文件,减少手动的代码输入。
APT是一个命令行工具,它对源代码文件进行检测找出其中的annotation后,使用AbstractProcessor来处理annotation。
JavaPoet + Auto Service + java APT完成对编译时注解的处理。
compile 'com.squareup:javapoet:1.9.0'
在JavaPoet中,JavaFile是对.java文件的抽象,TypeSpec是类/接口/枚举的抽象,MethodSpec是方法/构造函数的抽象,FieldSpec是成员变量/字段的抽象。
11. Android studio中使用APT过程:
(1) 创建android过程SelfAnnotationProcessor
(2) 给工程添加java module:名称 apt: 主要用于处理运行时注解的解析工作;
给工程添加java module:名称 anno: 主要用于定义运行时注解;
(3) 在app module的build.gradle添加依赖
annotationProcessorproject(":apt")
implementationproject(':anno')
在apt module的build.gradle添加依赖
Implementation project(‘:anno’)
implementation'com.squareup:javapoet:1.11.1'
implementation'com.google.auto.service:auto-service:1.0-rc2'
(4) 在 anno module下定义注解:
(5) 在app module的MainActivity中使用自定义注解 BindSelfView
(6) 在apt module下定义自定义注解处理器(代码太长)
添加了 @AutoService(Processor.class)
那么就会在当前工程apt的META-INF下生成配置文件, 内容为注册的注解处理器。
在init方法中进行工具类对象的获取:
在核心方法process里面对 被注解元素进行分析,并生成目标文件;
整个过程中用到TypeSpec,MethodSpec,JavaFile等对象
其中用到了javapoet的提供的API
(7) 然后执行build(rebuild)操作,就可以在 app module下看到生成的目标文件
至此一个简单的对于编译时注解的解析工作算是基本完成.
github:
https://github.com/catchMouse/SelfAnnotationProcessor //这是一个单纯编译时注解的demo
https://github.com/catchMouse/butterknife_like //网上提供的编译时注解处理demo,编译后生成中间文件,可以在MainActivity中进行运行时资源获取,我在其中各个步骤都加了注释,这对理解butterknife的整个源码过程是有帮助的