Java 注解: 元注解, 元素类型与保留策略

注解是一种元数据形式, 为有关程序提供数据, 但这些数据并不属于程序本身. 注解对其注解代码的操作不产生直接影响.

注解有许多用途, 其中包括:

  • 处理编译器信息: 编译器可以使用注解来检测错误或抑制警告
  • 编译和部署时处理: 程序工具可以处理注解信息以生成代码、XML 文件等
  • 运行时处理: 一些注解可以在运行时检查

下面我们将介绍, 注解的基本使用, 如何声明一个注解, 元注解, 常见注解以及可重复的注解

1. 注解的使用

常见的注解使用如下:

@Annotation(value = "xxx", num = 3)
class Demo {
}

这是个以 @ 符号开头的注解, 用于注解 Demo 类元素, 所有被注解所注解的代码都称之为元素, 包括但不限于, 参数, 类, 方法. 在示例中, class Demo 就是被注解的元素, 在注解后的括号里的 value = "xxx" 是指注解中的元素成员值(注意, 这里的元素不同于上面所说的元素, 这里的元素成员类似于类中的属性, 是注解内的成员), 而代码中的 num 就是另一个元素成员的名称, 类型是一个整型.

其实我们可能不经意间就已经使用过注解了, 比如 @Override, 该注解实现了对所覆盖的方法的编译性约束, 即如果子类中所覆盖的方法, 如果声明方式与超类中不一致, 则会发出一个错误报告:

The method xxxMethod() of type XXXClass must override or implement a supertype method

2. 注解的声明

解下下来, 我们将简单的声明一个注解:

@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Book {
    String value() default "";
    String author() default "";
    float price() default 0.0f;
}

在上面的代码中, 我们声明了一个注解 Book , 这里我们应该也注意到了, 注解是一种类接口的实现, 但是他使用的 @interface 声名. 同时, 我们还注意到了我们声明的注解, 也被注解了, 这种定义在 Java 中的注解我们称之为元注解 (meta-annotation), 他规定了注解的各种行为模式, 比如 @Documented 指明是否在文档中显示, @Target 指明了注解的作用对象(即元素)的类型, @Retention 指明了注解的保留时效, 这里指明注解只保留于源码中, 不保留在 .class 类文件中, 更不会进入VM的运行时.这里我们同样需要注意的是, 注解的元素成员的声明是带括号的, 比如 value()author(), 元素成员是要指定类型的, 将元素类型声明为数组型也是可以的, 同时能够通过 default 关键词为元素成员提供默认值.

结合注解的基本使用, 我们可以以如下的方式使用上例中声明的注解

@Book(value = "傲慢与偏见", author = "简·奥斯汀", price = 19.9f)
public static class ReadNote {

}

在上面的使用使用中, 我们提供了 @Book 注解的所有元素成员的值: value, author, price

//相当于 @Book(value = "朝花夕拾")
@Book("朝花夕拾")
public static class ReadNote2 {
}

在这里, 因为所有元素成员都默认值, 所以我们直接使用 "朝花夕拾", 为 value() 成员提供了值. value() 成员是一种特殊的注解元素成员.在只需要提供 value() 元素成员值的情况下, 是可以不提供元素成员名.

3. 元注解

在上面我们初步接触到了什么是元注解, 即 Java 中预定义的用于注解后约束所注解的注解的注解. 拆开来说就是元注解本身也是一种注解, 它注解的元素类型是注解, 用以约束所注解的注解的行为. 元注解的详细列表如下:

名称说明
Documented

如果注解 @Documented 修饰在注解类型 A 的声明中, 则元素上的任何 @A 注解都被视为元素公共约定的一部分.

Inherited

指明一个注解类型是否是能被元素的子元素自动继承的

Native

指明一个定义了常量值的字段也许能被本地代码所引用.

Repeatable

注解类型 Repeatable 用于指明它作为元注解所声明的注解类型是可重复的. 也就是用 @Repeatable 声明的注解 A, 可以作为容器注解, A 保证了被其注解的注解可以重复使用.

Retention

指明被 @Retention 注解声明的注解类型可以保留多长时间.

Target

指明了注解类型所适用的上下文, 即声明的注解所能注解的元素类型.

其中 @Target 的值是 ElementType 枚举的任意个成员, 如果没有为注解指定 @Target 注解, 则表明注解可以适用于上下文, ElementType 枚举的成员列表如下:

  • ANNOTATION_TYPE 枚举 ElementType 的元素, 适用于注解类型的声明
  • CONSTRUCTOR 枚举 ElementType 的元素, 适用于构造方法的声明
  • FIELD 枚举 ElementType 的元素, 适用于注解字段的声明, 包括 enum 常量.
  • LOCAL_VARIABLE 枚举 ElementType 的元素, 适用于注解本地变量的声明
  • METHOD 枚举 ElementType 的元素, 适用于注解方法的声明
  • MODULE 枚举 ElementType 的元素, 适用于注解模块的声明
  • PACKAGE 枚举 ElementType 的元素, 适用于注解包的声明
  • PARAMETER 枚举 ElementType 的元素, 适用于形式参数的声明
  • TYPE 枚举 ElementType 的元素, 适用于类, 接口(包括注解), 枚举的声明
  • TYPE_PARAMETER 枚举 ElementType 的元素, 适用于类型参数的声明
  • TYPE_USE 枚举 ElementType 的元素, 用在一个类的各个方面

而 @Retetion 的值是 RetetionPolicy 枚举的单个成员, 如果没有为注解指定 @Retetion 注解, 则默认表明注解采用 RetentionPolicy.CLASS 策略,  RetetionPolicy 枚值的成员列表如下:

  • CLASS 注解将由编译器记录在 .class 文件中, 但不需要在运行时由 VM 保留.
  • RUNTIME 注解将由编译器记录在 .class 文件中, 并在运行时由 VM 保留, 因此可以通过反射读取它们.
  • SOURCE 注解将被编译器丢弃, 只保留在源码中.

4. Java中预定义的注解

除了元注解这种预定义的注解之外, 还有一些能够帮我们约束代码编写, 更多的Java中预定义的注解, 列表如下:

名称说明
Deprecated

带有 @Deprecated 注解的程序元素都是不鼓励程序员使用的程序元素.

FunctionalInterface

FunctionalInterface 是一种信息性的注解类型, 用于指明接口类型声明旨在成为符合 Java 语言规范 所定义的函数接口.

Override

指明方法声明覆盖了超类中的方法声明.

SafeVarargs

使用 @SafeVarargs 表明程序员断定带注解的方法或构造函数的主体不会对其 varargs 参数执行潜在的不安全操作.

SuppressWarnings

@SuppressWarnings 指明应在带注解的元素中(以及在带注解的元素中包含的所有程序元素中)抑制指名(指出名字)的编译器警告.

5. 可重复注解

一个注解能否重复注解同一个元素呢? 结果是显然的, 上面的元注解列表中已经提到了 @Repeatable 注解. 那么如何实现呢?

首先我们需要声明一个可重复注解 R 的容器注解 C (也就是存放注解的注解);

然后再用以 C 类型为元素成员值的  @Repeatable 注解来注解可重复注解 R, 来表明 R 是可重复使用的注解.

最后这个注解 R 就可以重复注解到要注解的元素上的了.

示例如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
private @interface Container {
    Element[] value();
}

@Repeatable(Container.class)
private @interface Element {
    String value() default "";
}

@Element("准备")
@Element("发令")
@Element("跑")
@Element("冲线")
private class Running {

}

在实例中, 我们首先声明了可重复注解 Element 的的容器注解 Container, 然后使用以 Container.class 为元素成员值 @Repeatable 注解来注解可重复的注解 Element , 然后就可以用 Element 注解重复的注解到 Running 类上了.

本文首发: Java 注解: 元注解, 元素类型与保留策略 - 21yi.comicon-default.png?t=M276https://21yi.com/java/java-annotation-meta-annotion-element-type-and-retension-policy_10454.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值