概述
注解是一种能被添加到java代码中的元数据, 类、方法、变量、参数和包都可以用注解来修饰。注解对于它所修饰的代码并没有直接的影响。Annatation是一个接口,程序可以通过反射来获取指定程序中元素的 Annotation对象,然后通过该 Annotation 对象来获取注解中的元数据信息。注解其实就是一种标记,可以在程序代码中的关键节点(类、方法、变量、参数、包)上打上这些标记,然后程序在编译时或运行时可以检测到这些标记从而执行一些特殊操作
注解的用法:
-
为编译器提供信息 - 注解能被编译器检测到错误或抑制警告。
-
编译时和部署时的处理 - 软件工具能处理注解信息从而生成代码,XML文件等等。
-
运行时的处理 - 有些注解在运行时能被检测到。
自定义注解:
-
定义注解——相当于定义标记;
-
配置注解——把标记打在需要用到的程序代码中;
-
第三步,解析注解——在编译期或运行时检测到标记,并进行特殊操作。
基本语法
注解类型的声明部分,注解在Java中,与类、接口、枚举类似,因此其声明语法基本一致,使用@interface关键字。在底层实现上,所有定义的注解都会自动继承 java.lang.annotation.Annotation 接口。
注解类型的实现部分,在自定义注解中,其实现部分只能定义一个东西:注解类型元素(annotation type element)。定义注解类型元素时需要注意如下几点:
-
访问修饰符必须为public,不写默认为public;
-
该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型;
-
该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value;
-
()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法;
-
default代表默认值,值必须和第2点定义的类型一致;
-
如果没有默认值,代表后续使用注解时必须给该类型元素赋值。
元注解
元注解:专门修饰注解的注解,它们都是为了更好的设计自定义注解的细节而专门设计的。
@Target:是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的。它使用一个枚举类型定义如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
public enum ElementType {
TYPE, // 类
FIELD, // 属性 字段
METHOD, // 方法
PARAMETER, // 参数
CONSTRUCTOR, // 构造方法
LOCAL_VARIABLE, // 局部变量
ANNOTATION_TYPE, // 注解类型
PACKAGE, // 包注解
/** Type parameter declaration */
TYPE_PARAMETER,
/** Use of a type */
TYPE_USE
}
@Retention:翻译为持久力、保持力。即用来修饰自定义注解的生命力。注解的生命周期有三个阶段:Java源文件阶段;编译到class文件阶段;运行期阶段。RetentionPolicy枚举类型定义了三个阶段:
-
如果一个注解被定义为RetentionPolicy.SOURCE,则它将被限定在Java源文件中,那么这个注解即不会参与编译也不会在运行期起任何作用,这个注解就和一个注释是一样的效果,只能被阅读Java文件的人看到;
-
如果一个注解被定义为RetentionPolicy.CLASS,则它将被编译到Class文件中,那么编译器可以在编译时根据注解做一些处理动作,但是运行时JVM(Java虚拟机)会忽略它,我们在运行期也不能读取到;
-
如果一个注解被定义为RetentionPolicy.RUNTIME,那么这个注解可以在运行期的加载阶段被加载到Class对象中。那么在程序运行阶段,我们可以通过反射得到这个注解,并通过判断是否有这个注解或这个注解中属性的值,从而执行不同的程序代码段。我们实际开发中的自定义注解几乎都是使用的RetentionPolicy.RUNTIME;
public enum RetentionPolicy {
/**
* (注解将被编译器忽略掉)
*/
SOURCE,
/**(注解将被编译器记录在class文件中,但在运行时不会被虚拟机保留,这是一个默认的行为)
*/
CLASS,
/**
* (注解将被编译器记录在class文件中,而且在运行时会被虚拟机保留,因此它们能通过反射被读取到)
*/
RUNTIME
}
@Documented 注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的,但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理,所以注解类型信息也会被包括在生成的文档中,是一个标记注解,没有成员