在本系列的头三个讲解中,我们学习了什么是注解、如何定义注解、以及如何配置注解。那么当做好了这一切,这样的注解在实际中又有什么样的作用呢?这就是我们今天要讨论的:让编写期配置在Java文件的注解影响运行期的效果,即下图的第三步。
回顾
我们在前面定义了一个叫LovoAnnotation的注解,并且把它配置在了类Student上,具体代码如下:
|
|
那么接下来,我们就以此为例来演示在运行时解析配置在Student类上面的@LovoAnnotation的信息。
运行时解析
确认注解的保持力
在定义注解的时候有一个元注解叫@Retention。这个注解是专门用来描述自定义注解的保持力。说白了就是这个注解能在存在于源代码、class文件、运行期三个阶段中的哪一个。只有当一个注解,使用了@Retention(RetentionPolicy.RUNTIME)修饰,才表示这个注解能够保持到运行期。也只有这种情况我们才可以在运行期获取到它。所以,首先一定要确认这一点。
反射操作获取注解
在运行期探究和使用编译期的内容,当然要用到Java中的开挂技术—反射!
解释一下:
- 如果我们要获得的注解是配置在类型上的,那么我们要从Class 对象上获取;如果是配置在属性、构造、普通方法等元素上,那么要从该属性对应的Field对象、该构造对应的Constructor对象、该方法对应的Method对象等反射对象上获取;
- isAnnotationPresent(注解.class)方法是专门判断是否配置有某个指定的注解对象;
- getAnnotation(注解.class)方法是获取指定的注解,然后在调用该注解的注解类型元素方法就可以获得配置时的值数据;
- 反射对象上还有一个方法getAnnotations(),该方法可以获得该对象身上配置的所有的注解。它会返回给我们一个注解数组,需要注意的是该数组的类型是Annotation类型,这个Annotation是一个来自于java.lang.annotation包的接口(我们曾在本系列的第一章介绍过它,记不住就回头去看看)。
|
|
- 如果我们的注解使用了元注解@Inherited修饰的话,那么Student的子类无需配置也会自动具备来自于父类的注解。注意:这个特性仅限于@Target为ElementType.TYPE的注解。
|
|
大家自己测试一下这个结论吧。
总结
至此,我们就可以在运行期获得编写java文件时配置的各种注解了。虽然我们写了好几篇博客才搞定,但是其实语法并不复杂,只是我们讲解的比较细致而已。
在日常开发中,我们大家什么时候感受使用注解最多呢?当然是在各种JavaEE框架的配置中,我们很明显感受到以前很多框架的老版本都是使用的XML文件做配置,而今很多框架的新版本都改成了支持注解配置的方式。
那么,注解真的可以用来完全替代XML吗?请关注本系列的最后一节。
系列:
注解Annotation全解析(一):我不是注释
注解Annotation全解析(二):自定义注解的定义
注解Annotation全解析(三):自定义注解的配置使用
注解Annotation全解析(四):自定义注解的运行时解析
注解Annotation全解析(五):注解与XML的比较