跟王老师学注解:利用反射读取注解信息

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跟王老师学注解:利用反射读取注解信息相关的知识,希望对你有一定的参考价值。

跟王老师学注解(五):读取注解信息

主讲教师:王少华   QQ群号:483773664

一、注解被读取

(一)条件

当一个注解类型被定义为运行时注解后,该注解才是运行时可以见,当class文件被装载时被保存在class文件中的注解才会被Java虚拟机所读取。

要把@Retention注解的value成员变量的值设为RetentionPolicy.RUNTIME

(二)办法

我们已知所有的注解都是继承的java.lang.Annotation接口,也就是说Annotation是所有接口的父接口。除此之外,在java.lang.reflect包下的新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素,

技术分享

1、该接口有如下几个实现类,分别是:

Class:类定义

Constructor:构造方法定义

Field:类的成员变量定义

Method:类的方法定义

Package:类的包定义

技术分享

2、java.lang.reflect.AnnotatedElement接口是所有程序元素的父接口,程序通过反射获得某个类的AnnotatedElement对象,调用该对象的3个方法就可以来访问注解信息。

getAnnotation()方法:用于返回该程序元素上存在的、指定类型的注解,如果该类型的注解不存在,则返回null

getAnnotations():用来返回该程序元素上存在的所有注解。

isAnnotationPresent():用来判断该程序元素上是否包含指定类型的注解,如果存在返回true,否则返回false.

技术分享

二、示例

(一)输出类方法上的所有注解

1、自定义的annotation

1
2
3
4
5
6
7
8
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD,
    ElementType.PARAMETER, ElementType.CONSTRUCTOR,
    ElementType.LOCAL_VARIABLE })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String name() default "Jack";
    int age() default 20;
}

2、使用自定义Annotation

1
2
3
4
5
6
7
8
public class Person {
    private String name;
    private int age;
    @MyAnnotation
    public void setInfo(){
         
    }
}

3、测试

1
2
3
4
5
6
7
8
9
10
public class AnnotationTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
        Class<Person> personClass = (Class<Person>) Class.forName("chapter10_04.Person");
        Method method = personClass.getMethod("setInfo");
        Annotation[] annotations = method.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}

(二)获取某个注解里的元数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class AnnotationTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
        Class<Person> personClass = (Class<Person>) Class.forName("chapter10_04.Person");
        Method method = personClass.getMethod("setInfo");
        Annotation[] annotations = method.getAnnotations();
        for (Annotation annotation : annotations) {
            //如果类型是MyAnnotation
            if (annotation instanceof MyAnnotation) {
                System.out.println(annotation);
                //强制类型转换
                MyAnnotation myAnnotation = (MyAnnotation) annotation;
                //输出值
                System.out.println("myAnnotation.name:"+myAnnotation.name());
                System.out.println("myAnnotation.age:"+myAnnotation.age());
            }
        }
    }
}

三、@Inherited

@Inherited : 在您定义注解后并使用于程序代码上时,预设上父类别中的注解并不会被继承至子类别中,您可以在定义注解时加上java.lang.annotation.Inherited 限定的Annotation,这让您定义的Annotation型别被继承下来。注意注解继承只针对class 级别注解有效。

(一)改造MyAnnotation

1
2
3
4
5
6
7
8
9
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD,
    ElementType.PARAMETER, ElementType.CONSTRUCTOR,
    ElementType.LOCAL_VARIABLE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
    String name() default "Jack";
    int age() default 20;
}

(二)继承类及使用自定义注解

1
2
3
4
@MyAnnotation
public class Fruit {
 
}
1
2
3
public class Apple extends Fruit{
     
}

(三)获得父类的annotaion

1
2
3
4
5
6
7
8
9
public class AnnotationTest2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
        Class<Apple> appleClass = (Class<Apple>) Class.forName("chapter10_04.Apple");
        Annotation[] annotations = appleClass.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}






以上是关于跟王老师学注解:利用反射读取注解信息的主要内容,如果未能解决你的问题,请参考以下文章

注解与反射

跟王老师学注解:注解应用案例

反射机制读取注解

反射读取注解信息

跟王老师学注解:元注解

跟王老师学注解:自定义注解