jkd1.8中文API (可以在API中查看相关类的说明,介绍很详细)
参考《Android进阶之光》第九章注解与依赖注入框架
注解学习之注解基础
注解学习之依赖注入框架ButterKnife
注解概述
注解类型:
1.标准注解
Java中定义好的注解类型
- @Override:对覆盖超类中的方法进行标记
- @Deprecated:对不使用或已过时的方法添加注解
- @SuppressWarnings: 选择性的取消特定代码中的警告
2.元注解
元注解用来修饰注解接口,从而确定一个注解接口的使用方式
@Target:注解修饰的对象范围
- ElementType.TYPE: 修饰类,接口或枚举类型
- ElementType.FIELD:修饰成员变量
- ElementType.PARAMETR:修饰参数
- ElementType.METHOD:修饰方法
- 等等
@Retention:声明注解的保留策略
- Retention.RUNTIME: 运行时注解
- Retention.SOURCE: 源码级注解
- Retention.CLASS: 编译时注解
@Inherited:表示注解可以被继承
@Document:表示这个注解应该被JavaDoc工具记录
例子学习
1. 运行时注解处理器
定义注解
@Documented
@Retention(RetentionPolicy.RUNTIME) //保留策略为运行时
@Target(ElementType.METHOD) //规定此注解修饰方法
public @interface Swordsman {
String name() default "android";//定义成员变量
int age() default 10;
}
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GET {
String value() default "192.168.0.1";
}
注解处理器
package annotation;
import java.lang.reflect.Method;
public class AnnotationProcessor {
public static void main(String[] args) {
//获取这个类的公共方法
Method[] methods = AnnotationTest.class.getDeclaredMethods();
//遍历这个类的公共方法
for (Method method : methods){
//判断这个方法是否有swordsman注解, Method ,Class, Filed等实现了AnnotatedElement
if (method.isAnnotationPresent(Swordsman.class)){
Swordsman swordsman1 = method.getAnnotation(Swordsman.class);
System.out.println(" swordsman "+swordsman1.name());
}
//判断这个方法是否有GET注解
if (method.isAnnotationPresent(GET.class)){
GET get = method.getAnnotation(GET.class);
System.out.println("Get 值 "+get.value());
}
}
}
}
2.编译时注解处理器
Android buildGradle 在3.0版本之后采用 annotationProcessor加载注解库
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
compileOnly 'com.google.auto.service:auto-service:1.0-rc4'
//这个要加上否则可能生成不了服务文件
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc4'
implementation project(":annotations")
}
定义注解
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface BindView {
int value() default 1;
}
注解解释器
//继承:AbstractProcessor:一个抽象的注释处理器,被设计为大多数具体注解处理器的一个方便的超类。
@AutoService(Processor.class)
public class ClassProcessor extends AbstractProcessor {
/**
* @param processingEnvironment 由工具框架返回的处理环境
*/
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
System.out.println("注解处理工具调用");
super.init(processingEnvironment);
}
/**
*
* @param roundEnvironment 用于查询一轮注释处理的信息
*/
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
//TODO Messager 提供注释处理器报告错误消息,警告和其他通知的方式
Messager messager = processingEnv.getMessager();
//返回使用给定注释类型的元素
for (Element element : roundEnvironment.getElementsAnnotatedWith(BindView.class)){
//获取元素的类型 TODO: Element 表示程序元素,如程序包,类、方法、属性等
if (element.getKind() == ElementKind.FIELD){
//打印指定类型的属性名 在这里是打印属性名
messager.printMessage(Diagnostic.Kind.NOTE,"printMessage: "+element.toString());
//打印注解值
messager.printMessage(Diagnostic.Kind.NOTE,"printMessage: "+element.getAnnotation(BindView.class).value());
}
}
return true;
}
/**
* 返回此处理器支持的注释类型的名称
*/
@Override
public Set<String> getSupportedAnnotationTypes() {
//指定这个注解器是注册给哪个注解的
Set<String> annotations = new LinkedHashSet<>();
annotations.add(BindView.class.getCanonicalName());
System.out.println("获取集合 : "+annotations);
return annotations;
}
@Override
public SourceVersion getSupportedSourceVersion() {
//用来指定使用的Java版本
return SourceVersion.latestSupported();
}
}