- 从 Java 5 开始出现
- Annotaticm 能被用来为程序元素( 类、方法、成员变量等)设置元数据
- 所有注解都隐式继承了 Annotation java.lang.annotation.Annotation 接口
基本 Annotation
在 java.lang 包下
@Override
限定重写父类方法@Deprecated
标示已过时(与文档注释中的 @deprecated 标记的作用基本相同)@SuppressWarnings("变量值")
抑制编译器警告(常见的变量值:unused, rawtypes, unchecked, serial, deprecation, all)@SafeVarargs
抑制编译器“堆污染”警告(Java 7 新增)@FunctionalInterface
函数式接口(接口中只有一个抽象方法)(Java 8 新增)
JDK 的元 Annotation
在 java.lang.annotation 包下,用于修饰其它的 Annotation 定义
@Target
:用于指定被修饰的注解能用于修饰哪些程序元素常量值封装在 ElementType 枚举类中:TYPE、FIELD、CONSTRUCTOR、METHOD、LOCAL_VARIABLE、PACKAGE、PARAMETER、ANNOTATION_TYPE@Retention
:用于指定被修饰的注解可以保留多长时间常量值封装在 RetentionPolicy 枚举类中:SOURCE、CLASS(默认值)、RUNTIME@Documented
:其修饰的注解会保存到 API 文档中@Inherited
:其修饰的注解可以被子类所继承
自定义 Annotation
- Annotation 中的属性以无参数的抽象方法的形式来定义
- 属性的类型只能是基本类型、String、Class、annotation、枚举及这些类型一维数组
- 在定义 Annotation 的属性时可以使用
default
为其指定默认值 - 使用带属性的注解时,必须为该注解的所有没有默认值的属性指定值
- 对于 Annotation 中变量名为 value属性,在使用该注解时可以直接在该注解后的括号里指定 value 属性的值,无须使用“value = 变量值”的形式
public @interface MyTag1 {
String name();
int age();
}
// 使用
@MyTag1(name="xx", age=6)
public @interface MyTag2 {
// 使用 default 为两个成员变量指定初始值
String name() default "admin";
int age() default 17;
}
// 使用
@MyTag2
// 获取程序元素上的注解 @MyTag2 的成员变量的值
程序元素.getAnnotation(MyTag2.Class).成员变量名()
通过反射获取程序元素的 Annotation 信息
只能提取使用了
@Retention(RetentionPolicy.RUNTIME)
修饰的注解AnnotatedElement 接口是所有程序元素(Class、Constructor、Field、Method、Package ) 的父接口
AnnotatedElement 接口中的方法
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
:判断该程序元素上是否存在指定类型的注解<A extends Annotation> A getAnnotation(Class<A> annotationClass)
:返回该程序元素上存在的、指定类型的注解,如果不存在,则返回 null(包括继承的注释)Annotation[] getAnnotations()
:返回该程序元素上存在的所有注解(包括继承的注释)Annotation[] getDeclaredAnnotations ()
:返回直接修饰该程序元素的所有 Annotation
编译时处理 Annotation
- 注解处理工具 APT(Annotation Processing Tool)