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

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

主讲教师:王少华   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);

        }

    }

}

来自为知笔记(Wiz)

时间: 2024-11-03 17:48:27

跟王老师学注解(五):利用反射读取注解信息的相关文章

Java 自定义注解及利用反射读取注解

一.自定义注解 元注解: @interface注解: 定义注解接口 @Target注解: 用于约束被描述的注解的使用范围,当被描述的注解超出使用范围则编译失败.如:ElementType.METHOD,ElementType.TYPE: @Retention 注解:用于约束被定义注解的作用范围,作用范围有三个: 1,.RetentionPolicy.SOURCE:作用范围是源码,作用于Java文件中,当执行javac时去除该注解. 2.RetentionPolicy.CLASS:作用范围是二进制

跟王老师学反射(五):使用反射生成并操作对象

跟王老师学反射(五):使用反射生成对象 主讲教师:王少华   QQ群号:483773664 学习内容 使用反射生成对象 模板类 一.创建对象 (一).非反射方法 (二).反射方式 通过构造方法生成对象,有二种方式,一种通过无参的构造方法,一种是通过有参的构造方法. 1.无参构造方法 1.1 如果无参数的构造方法是public 也可以使用Class对象的newInstance()方法来创建该Class对象对应类的实例 1.2 如果无参构造方法是私有化的 结论 如果无参构造访问,是私有化的,一定要使

跟王老师学反射(一):反射概述

跟王老师学反射(一) java反射概述 主讲教师:王少华   QQ群号:483773664 学习目标: 理解Java反射机制 一.什么是Java反射 现实生活,我们会看到这样的现象,在很多影视城,会看到很多山寨版的古代的建筑,比如故宫,但是由于年代久远,故宫的建筑图纸,丢失了(我们假设故宫的图纸丢失了),这样我们就必须依据现在的故宫实体建筑,画出它的图纸,然后依据现画好来的图纸,来建造山寨版的故宫.这样一个由实物得到图纸的过程,我们也可以称之为"反射过程" Reflection(反射)

跟王老师学反射(二):Java类的加载、连接和初始化

跟王老师学反射(二):Java类的加载.连接和初始化 主讲教师:王少华   QQ群号:483773664 学习内容: 了解类的加载.连接和初始化 一.类的生命周期 当我们编写一个java的源文件后,经过编译会生成一个后缀名为class的文件,这种文件叫做字节码文件,只有这种字节码文件才能够在java虚拟机中运行,java类的生命周期就是指一个class文件从加载到卸载的全过程.一个java类的完整的生命周期会经历加载.连接.初始化.使用.和卸载五个阶段,当然也有在加载或者连接之后没有被初始化就直

跟王老师学反射(三):Class类:获得Class对象

跟王老师学反射(三):Class类:获得Class对象 主讲教师:王少华   QQ群号:483773664 学习内容 掌握获得Class对象的三种方式 理解这三种方式的区别 一.获得Class对象 前面我们已经领略了反射的魅力了,我们知道,利用反射的关键是要获得"图纸"Class对象,那么怎么获得这个Class对象呢!!! 每个类被加载之后,系统会为该类生成一个对应的Class对象,通过该Class对象就可以访问JVM中的这个类.Java程序获得Class对象有如下三种方式: (一)调

跟王老师学反射(四):Class类:从Class类中获取信息

跟王老师学反射(四)Class类:从Class类中获取信息 主讲教师:王少华   QQ群号:483773664 学习内容 获得class类中的信息 根据我们以前学过的一个Java类有以下几部组成,如下代码所示 一.访问Class对应的类所包含的构造方法 (一)public Constructor<T> getConstructor(Class<?>... parameterTypes) 返回此Class对象所表示的类的指定public构造方法. parameterTypes参数是按

跟王老师学反射(八):使用反射操作数组

跟王老师学反射(八):使用反射操作数组 主讲教师:王少华   QQ群号:483773664 学习内容 使用反射操作数组 在java.lang.reflect包下还提供了一个Array类,Array对象可以代表所有的数组.程序可以通过使用Array来动态创建数组. 一.传统的创建数组的方法 1 2 3 4 5 6 7 8 public   static   void  main(String[] args)  {        int vec[] = new int[]{1, 5, 3};  //

跟王老师学注解(三):元注解

跟王老师学注解(三):元注解 主讲教师:王少华   QQ群号:483773664 元注解,是用来修饰其他的注解定义.java.lang.annotation包下提供了4个元注解,分别是@Target注解.@Retention注解.@Documented注解以及@Inherited注解. 一.@Target (一)简介 用于指定被修饰的注解能用于修饰哪些程序元素 @Target注解类型有唯一的value作为成员变量,value的类型为java.lang.annotation.ElementType

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

跟王老师学注解(六):注解应用案例 主讲教师:王少华   QQ群号:483773664 一.需求 利用注解,做一个Bean的数据校验 要求: 用户名是否能为空,用户名的长度不能超过指定长度,不能少于指定长度 二.参考代码 @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD, ElementType.PARAMETER }) public @interface MyValidate {     // 是否可以为空