注解

Annotation

概念

能够添加到 Java 源代码的语法元数据。类、方法、变量、参数、包都可以被注解,可用来将信息元数据与程序元素进行关联。Annotation 中文常译为“注解”。

注解不会改变程序被编译的方式。不管有没有被注解,Java 编译器都会产生相同的虚拟机指令。

注解元素

  • 基本类型值
  • String(字符串)
  • Class对象
  • enum(枚举)实例
  • 注解
  • 由前面几种类型组成的数组(但不能是数组的数组)

例如:

@MyAnnotation(showImg = true,
    loginName = "nvgtor",
    testCase = CacheTest.class,
    status = MyAnnotation.Status.CONFIRMED)

元素可以有默认值。

注解的类型可以分为两类:声明和类型用途

注解声明

声明注解可以出现在如下情况里:

  • 类(包括 enum)和接口(包括注解接口)
  • 方法
  • 构造函数
  • 实例变量(包括 enum常量)
  • 局部变量(包括在 for 中声明的局部变量)
  • 参数变量和 catch 子句参数
  • 类型参数

注解类型用途

例如:

// 断言参数 userId 不能为 null
public User getUser(@NonNull String userId)

//所有字符串都是非空
List<@NonNull String>

类型用途注解可以出现在一下地方:

  • 带泛型类型的参数: List<@NonNull String>
  • 在数组的任何位置: @NonNull String[][] words(words[i][j] 非空),String @NonNull [][] words(words非空), String[] @NonNull [] words(words[i] 非空)
  • 父类和被实现接口
  • 构造函数调用
  • 嵌套类型
  • 。。。

定义注解

每个注解必须通过一个注解接口(以 @interface 语法)声明。接口的方法对应注解的元素。如:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
      public String key();
      public String user();
}

@interface 声明会创建一个实际的 java 接口。处理注解的工具会接受实现了注解接口的对象。注解接口中的元素声明实际上是方法声明。注解接口的方法没有参数,不能有 throws 语句,也不能是泛型的。

  • 所有方法没有方法体,没有参数没有修饰符,实际只允许 public & abstract 修饰符,默认为 public ,不允许抛异常
  • 方法返回值只能是基本类型,String, Class, annotation, enumeration 或者是他们的一维数组
  • 若只有一个默认属性,可直接用 value() 函数。一个属性都没有表示该 Annotation 为 Mark Annotation

元注解

  1. @Documented 是否会保存到 Javadoc 文档中
  2. @Retention 保留时间,可选值 SOURCE(源码时),CLASS(编译时),RUNTIME(运行时),默认为 CLASS,值为 SOURCE 大都为 Mark Annotation,这类 Annotation 大都用来校验,比如 Override, Deprecated, SuppressWarnings
  3. @Target 可以用来修饰哪些程序元素,如 TYPE, METHOD, CONSTRUCTOR, FIELD, PARAMETER 等,未标注则表示可修饰所有
  4. @Inherited 是否可以被继承,默认为 false

编译相关的注解

  1. @Deprecated 不再鼓励使用, 过时的
  2. @Override 使得编译器检查被注解的方法是否真的重载了一个来自父类的方法。
  3. @SuppressWarning 告诉编译器抑制一个特定类型的警告。
  4. @SafeVarargs 用于断言一个方法不损坏它的可变参数。
  5. @Generated 给代码生成工具使用
  6. @FunctionalInterface 用来为 lambda 表达式注解转换目标。

一篇很好的博客:

Annotation 示例、概念及作用、分类、自定义、解析,并对几个 Android 开源库 Annotation 原理进行简析。