本文是Java注解篇,学习于廖雪峰的Java教程

Java注解

1.注解

  • 注解(Annotation)是一种特殊的注释,作用于Java源码的类,方法,字段,参数前。
  • 注解与代码的关系:从JVM的角度看,注解本身对代码的逻辑没有任何影响。
  • 注解分类
    • 作用于编译器,但不会进入.class件,编译后不复存在,例如
      • @override告诉编译器检查是否进行了正确的代码覆写
      • @suppressWarning告诉编译器忽略当前产生的编译警告。
    • 作用于class文件,但加载后不会存在于内存中。
    • 作用于JVM,在程序运行时能够读取,例如
      • 配置了@PostConstruct参数的方法在调用构造方法时被自动调用。
  • 注解的配置参数必须是常量,注解的配置参数可以有默认值。

2.定义注解

  • 使用@interface语法来定义注解,并且可用default定义一个默认值,格式如下
public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
}
  • 元注解(meta annotation)可以修饰其他注解。

    • @Target声明注解可以作用于源码的哪个部分。
      • 类或接口:ElementType.TYPE
      • 字段:ElementType.FIELD
      • 方法:ElementType.METHOD
      • 构造方法:ElementType.CONSTRUCTOR
      • 方法参数:ElementType.PARAMETER
      • 示例代码
    @Target({
        ElementType.METHOD,
        ElementType.FIELD
    })
    public @interface Report {
        ...
    }
  • @Retention定于注解的生命周期

    • 仅编译期:RetentionPolicy.SOURCE
    • 仅class文件:RetentionPolicy.CLASS
    • 运行期:RetentionPolicy.RUNTIME
      • @Repeatable定义注解是否可重复。
      • @Inherited定义注解是否可继承,@Inherited仅针对@Target(ElementType.TYPE)类型的注解有效。
    @Repeatable(Reports.class)
    @Inherited
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Report {
        int type() default 0;
        String level() default "info";
        String value() default "";
    }

3.处理注解

  • 注解本身也是一种class,它继承自java.lang.annotation.Annotation

  • 利用反射API读取注解

    • 判断某个注解是否存在
      • Class.isAnnotationPresent(Class)判断类中是否存在某个注解。
      • Field.isAnnotationPresent(Class)判断字段中是否存在某个注解。
      • Method.isAnnotationPresent(Class)判断方法中是否存在某个注解。
      • Constructor.isAnnotationPresent(Class)判断构造方法中是否存在某个注解。
    • 获取注解
      • Class.getAnnotation(Class)获取类的某个注解
      • Method.getAnnotation(Class)获取方法的某个注解
      • Field.getAnnotation(Class)获取字段的某个注解
      • Constructor.getAnnotation(Class) 获取构造器的某个注解
      • 因为方法参数本身可以有多个注解,所以方法参数可以用二维数组表示。
  • 使用注解

    • 因为注解本身并不破坏代码逻辑,所以我们需要额外编写代码来使用注解。
    • 可以配合check()方法来使用注解。