• 从 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 = 变量值”的形式
  1. public @interface MyTag1 {
  2. String name();
  3. int age();
  4. }
  5. // 使用
  6. @MyTag1(name="xx", age=6)
  7. public @interface MyTag2 {
  8. // 使用 default 为两个成员变量指定初始值
  9. String name() default "admin";
  10. int age() default 17;
  11. }
  12. // 使用
  13. @MyTag2
  14. // 获取程序元素上的注解 @MyTag2 的成员变量的值
  15. 程序元素.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)