使用反射获取注解信息
使用注解修饰了类、方法、变量等成员之后,这些注解不会自己生效,必须由开发者提供相应的工具来提取处理。要想获取类、方法或变量的注解信息,必须通过 Java 的反射技术来获取 Annotation 对象,除此之外没有其它方法。
所有 Java 注解类型都继承于 java.lang.annotation.Annotation 接口,该接口代表程序中可以接收注解的程序元素。该接口主要有如下几个实现类。
- Class:类定义。
- Constructor:构造方法定义。
- Field:类的成员变量定义。
- Method:类的方法定义。
- Package:类的包定义。
java.lang.reflect 包下主要包含一些实现反射功能的工具类,从 Java 5 开始,java.lang.reflect 包所提供的反射 API 增加了读取运行时注解的能力。只有当定义注解时使用@Retention(RetentionPolicy.RUNTIME) 修饰,该注解才会在运行时可见。
AnnotatedElement 接口是所有程序元素(如 Class、Method、Constructor 等)的父接口,所以程序通过反射获取了某个类的 AnnotatedElement 对象(如 Class、Method、 Constructor 等)之后,程序就可以调用该对象的如下几个方法来访问注解信息,方法名称及作用如下表所示。
根据官方的命名规则,可以总结出以下几条:
- getDeclaredAnnotationXXXX:只可以获取直接存在的注解信息,即直接修饰在某个元素(类、属性和方法)上的注解。
- getXXXXByType:可以获取间接存在的注解信息
- getAnnotationXXX:可以获取继承的注解信息
所有的方法都可以获取直接注解信息
Demo
1)使用getAnnotation获取类的注解信息,并访问该注解的值,打印
package Annotation_Learning;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 练习使用反射获取注解类信息
*/
//定义一个注解
@Retention(RetentionPolicy.RUNTIME)//使注解运行时可见
@interface MyTag1{
String value() default "第一个注解的默认value值";
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyTag2{
String value() default "第二个注解的默认value值";
}
@MyTag1()
@MyTag2(value="第二个注解值设置为100")
public class ReflectandAnnotation {
public void test(){
System.out.println("进入类的test方法,只有当定义注解时使用@Retention(RetentionPolicy.RUNTIME) 修饰,该注解才会在运行时可见。");
}
public static void main(String[]args){
//第一步,创建对应的信息类
Class<?> test = ReflectandAnnotation.class;//这里使用泛型匹配类
//定义一个注解量接受返回值,返回值为注解类型,我们是使用类
MyTag1 myTag1 = test.getAnnotation(MyTag1.class);//所有这里test才能返回对应的值
System.out.println(myTag1.value());
MyTag2 myTag2 = test.getAnnotation(MyTag2.class);//所有这里test才能返回对应的值
System.out.println(myTag2.value());
}
}
运行结果:
Class<?> 中的 <?> 是必须写的,你可以把?改成要限定的类型,但是必须要写这个泛型限定才行,否则会编译错误。
2)下面我们使用 getAnnotations() 方法获取多个注解,并输出。
将上面的代码修改一下:
public static void main(String[]args){
//第一步,创建对应的信息类
Class<?> test = ReflectandAnnotation.class;//这里使用泛型匹配类
//定义一个注解量接受返回值,返回值为注解类型,我们是使用类
MyTag1 myTag1 = test.getAnnotation(MyTag1.class);//所有这里test才能返回对应的值
System.out.println(myTag1.value());
MyTag2 myTag2 = test.getAnnotation(MyTag2.class);//所有这里test才能返回对应的值
System.out.println(myTag2.value());
Annotation [] annotations = test.getAnnotations();
//使用for-each遍历
for(Annotation annotation:annotations){
System.out.println(annotation);
}
}
运行结果: