使用反射获取注解信息

使用注解修饰了类、方法、变量等成员之后,这些注解不会自己生效,必须由开发者提供相应的工具来提取处理。要想获取类、方法或变量的注解信息,必须通过 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 等)之后,程序就可以调用该对象的如下几个方法来访问注解信息,方法名称及作用如下表所示。

android注解反射 反射无法读取注解信息_spring


根据官方的命名规则,可以总结出以下几条:

  • 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());


        }

}

运行结果:

android注解反射 反射无法读取注解信息_java_02

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);
            }


        }

运行结果:

android注解反射 反射无法读取注解信息_spring_03