Java注解-Annotation架构+JDK元注解+如何自定义注解

it2024-01-29  62

java注解

1. 概述


首先,注解(Annotation)是一个接口,程序可以通过反射来获取指定程序元素的java.lang.annotation.Annotation对象。然后通过这个 对象来取得注解里的元数据。

只有通过某种配套的工具对注解中的信息进行访问和处理,注解才会影响程序的运行(在程序运行时起到一定的作用),否则,注解不会影响程序 的运行。访问和处理注解的工具统称为 APT(Annotation Processing Tool).

2. Annotation 架构

2.1 概述


“每 1 个 Annotation” 都与 “1 个 RetentionPolicy” 关联,并且与 “1~n 个 ElementType” 关联。可以通俗的理解为:每 1 个  Annotation 对象,都会有唯一的 RetentionPolicy 属性;至于 ElementType 属性,则有 1~n 个。

2.2 ElementType


ElementType 是 Enum 枚举类型,它用来指定 Annotation 的类型。每1个 Annotation 都与 1~n 个 ElementType关联。

当 Annotation 与某个 ElementType  关联时,就意味着:Annotation有了某种用途。

例如,若一个 Annotation 对象是 METHOD 类型,则该 Annotation 只能用来修饰方法。

2.3 RetentionPolicy


RetentionPolicy 是 Enum 枚举类型,它用来指定 Annotation 的策略。通俗点说,就是不同 RetentionPolicy 类型的  Annotation 的作用域不同。每 1 个 Annotation" 都与 "1 个 RetentionPolicy 关联。

若 Annotation 的类型为 SOURCE,则意味着:Annotation 仅存在于编译器处理期间,编译器处理完之后,该 Annotation  就没用了。例如," @Override" 标志就是一个  Annotation。当它修饰一个方法的时候,就意味着该方法覆盖父类的方法;并且在编 译期间会进行语法检查!编译器处理完后,"@Override"  就没有任何作用了。

若 Annotation 的类型为 CLASS,则意味着:编译器将 Annotation 存储于类对应的 .class 文件中,它是 Annotation  的默认行为。

若 Annotation 的类型为 RUNTIME,则意味着:编译器将 Annotation 存储于 class 文件中,并且可由JVM读入。

3. JDK的元注解

3.1 概述:


想要定义注解,我们必须依靠JDK的元注解

JDK在java.lang.annotation 下提供了6个 Meta注解(元注解),其中5个注解都用于修饰其他注解定义,只有@Repeatable 是专门定义java8新增的重复注解。这里只学习四个常用的注解。

@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。

@Documented - 标记这些注解是否包含在用户文档中。

@Target - 标记这个注解应该是哪种 Java 成员。

@Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

@Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

3.2 @Retention


只能用于修饰注解定义的,用于制定被修饰的注解,可以保留多长时间。他有三个值:

RetentionPolicy.SOURCE: 注解只保留在源代码中,编译器直接丢弃这种注解。

RetentionPolicy.CLASS:编译器把注解记录在class文件中,当运行程序时,JVM不可获取注解信息,这是默认值。

RetentionPolicy.RUNTIME:编译器将注解记录在class文件中,当运行Java程序时,JVM可以获取注解信息,程序可以通过反射获取该注解信息。

举例:@Retention(RetentionPolicy.RUNTIME) / @Retention(value = RetentionPolicy.RUNTIME)

3.3 @Target


也只能修饰注解定义,它用于指定被修饰的注解能用于修饰哪些程 序单元。它也包含一个名value的成员变量,该成员变量的值只能是以下几个

ElementType.ANNOTATION:指定该策略的注解只能修饰注解。

ElementType.CONSTRUCTOR:指定该策略的注解只能修饰构造器

ElementType.FIELD:指定该策略的注解只能修饰成员变量

ElementType.LOCAL_VARIABLE:指定该策略的注解只能修饰局部变量

ElementType.METHOD:指定该策略的注解只能修饰方法定义

ElementType.PACKAGE:指定该策略的注解只能修饰包定义

ElementType.PARAMETER:指定该策略的注解只能修饰参数

ElementType.TYPE:指定该策略的注解只能修饰类,接口(包括注解类型)或枚举类

举例:@Target(ElementType.METHOD)

3.4 @Documented


用于指定该元注解修饰的注解类将被javadoc工具提取成文档,如果定义注解类时使用了该修饰,则所有使用该注解修饰的程序元素的API文档中,将会包含该注解说明。

3.5 @Inherited


例子

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { }

该元注解指定被它修饰的注解将具有继承性。比如某个类使用了某个注解,该类的子类将自动被这个注解修饰

3.6 使用JDK的元注解创建自己的注解

例子

@Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation1 { }

定义注解时,要使用 @interface关键字,意味着它实现了 java.lang.annotation.Annotation 接口。

最新回复(0)