14.3.2 提取注解信息

14.3.2 提取注解信息

使用注解修饰了类、方法、成员变量等成员之后,这些注解不会自己生效,必须由开发者提供相应的工具来提取并处理注解信息。
Java使用java.lang.annotation.Annotation接口来代表程序元素前面的注解,该接口是所有注解的父接口。Java5java.lang.reflect包下新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素。该接口主要有如下几个实现类

AnnotatedElement接口实现类 描述
Class 类定义。
Constructor 构造器定义。
Field 类的成员变量定义
Method 类的方法定义。
Package 类的包定义。

java.lang.reflect包下主要包含一些实现反射功能的工具类,从Java5开始,java.lang.reflect包所提供的反射API增加了读取运行时注解的能力。只有当定义注解时使用了@Retention(RetentionPolicy.RUNTIME)修饰,该注解才会在运行时可见,JVM才会在装载*.class文件时读取保存在class文件中的注解信息

AnnotatedElement接口方法

AnnotatedElement接口是所有程序元素(如ClassMethodConstructor等)的父接口,所以程序通过反射获取了某个类的AnnotatedElement对象(如ClassMethodConstructor等)之后,程序就可以调用该对象的如下几个方法来访问注解信息。

方法 描述
<T extends Annotation> T getAnnotation(Class<T> annotationClass) 返回该程序元素上存在的、指定类型的注解,如果该类型的注解不存在,则返回null
Annotation[] getAnnotations() 返回该程序元素上存在的所有注解。
default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) 该方法的功能与前面介绍的getAnnotation()方法基本相似。但由于Java8增加了重复注解功能,因此需要使用该方法获取修饰该程序元素、指定类型的多个注解
default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) 这是Java8新增的方法,该方法尝试获取直接修饰该程序元素、指定类型的注解。如果该类型的注解不存在,则返回null
Annotation[] getDeclaredAnnotations() 返回直接修饰该程序元素的所有注解
default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) 该方法的功能与前面介绍的getDeclaredAnnotations()方法基本相似。但由于Java8增加了重复注解功能,因此需要使用该方法获取直接修饰该程序元素、指定类型的多个注解
default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 判断该程序元素上是否存在指定类型的注解,如果存在则返回true,否则返回false

程序 获取注解

下面程序片段用于获取Test类的info()方法里的所有注解,并将这些注解打印出来。

1
2
3
4
5
6
//获取Test类的info方法的所有注解
Annotation[] aArray = Class.forName("Test" ).getMethod("info").getAnnotations();
//遍历所有注解
for (Annotation an : aArray){
System.out.println(an);
}

如果需要获取某个注解里的元数据,则可以将注解强制类型转换成所需的注解类型,然后通过注解对象的抽象方法来访问这些元数据。如下代码片段所示。

未完待续…