注解是什么
注解就相当于对源代码打的标签,给代码打上标签和删除标签对源代码没有任何影响。
注解的工作原理
外部工具通过访问这些注解(标签),然后根据不同的注解(标签)做出了相应的处理
访问和处理的工具统称为APT(Annotation Processing Tool)
基本注解
| 注解 | 解释 |
|---|---|
| @Override | 让编译器检查被标记的方法,保证其重写了父类的某一个方法。此注解只能标记方法 |
| @Deprecated | 标记某些程序元素已经过时,程序员请不要再使用了 |
| @SuppressWarnings | 告诉编译器不要显示警告 |
| @SafeVarargs | java7新增,取消参数的警告 |
| @FunctionalInterface | java8新增,标记型注解,告诉编译器检查被标注的接口是否是一个函数接口 |
元注解
| 注解 | 说明 |
|---|---|
| @Retention | 用于指定被此元注解标注的注解的保留时长 |
| @Target | 用于指定被此元注解标注的注解可以标注的程序元素 |
| @Documented | 将被标注的注解生成到javadoc中 |
| @Inherited | 其让被修饰的注解拥有被继承的能力 |
| @Repeatable | 使被修饰的注解可以重复的注解某一个程序元素 |
RetentionPolicy有3种类型:
-
RetentionPolicy.SOURCE:
注解信息只保留在源代码中,编译器编译源码时会将其直接丢弃。
-
RetentionPolicy.CLASS
注解信息保留在class文件中,但是虚拟机VM不会持有其信息。
-
RetentionPolicy.RUNTIME
注解信息保留在class文件中,而且VM也会持有此注解信息,所以可以通过反射的方式获得注解信息。
自定义注解
注解是以关键字@interface 来定义的
没有成员变量
@Target(ElementType.METHOD)//只能应用于方法上。
@Retention(RetentionPolicy.RUNTIME)//保存到运行时
public @interface Test {
}
有成员变量(可以接收外界信息)
@Target(ElementType.TYPE)//只能应用于类型上,包括类,接口。
@Retention(RetentionPolicy.RUNTIME)//保存到运行时
public @interface Table {
String name() default "";
}
注解处理器
注解处理器(Annotation Processor)是javac的一个工具,它用来在编译时扫描和处理注解(Annotation)。
一个注解的注解处理器,以Java代码(或者编译过的字节码)作为输入,生成文件(通常是.java文件)作为输出
工作原理
将我们的源码使用特殊的注解标记,然后在编译成字节码的时候根据这些注解生成新的java源码,省去了我们自己编写此部分代码的工作量。
AbstractProcessor(Java内置注解处理器)
AbstractProcessor是一个抽象类
public class MyProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return super.getSupportedAnnotationTypes();
}
@Override
public SourceVersion getSupportedSourceVersion() {
return super.getSupportedSourceVersion();
}
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
return false;
}
}
- init:每一个注解处理器类都必须有一个空的构造函数。然而,这里有一个特殊的
init()方法,它会被注解处理工具调用,并输入ProcessingEnviroment参数 - process:处理器的主函数。在这里写扫描、评估和处理注解的代码,以及生成Java文件。输入参数
RoundEnviroment,可以让你查询出包含特定注解的被注解元素 - getSupportedAnnotationTypes:注解处理器是注册给哪个注解的。你在这里定义你的注解处理器注册到哪些注解上。
- getSupportedSourceVersion:指定使用的Java版本
在Android中使用@SupportedAnnotationTypes代替getSupportedAnnotationTypes(),使用@SupportedSourceVersion代替getSupportedSourceVersion()
注解处理器是运行它自己的虚拟机JVM中