Java编程之反射中的注解详解
“注解”这个词,可谓是在Java编程中出镜率比较高,而且也是一个老生常谈的话题。我们之前在聊Spring相关的东西时,注解是无处不在,之前我们简单的聊过一些“注解”的相关内容,比如在Spring中是如何进行“注解”组合的。因为注解在Java编程中还是比较重要的,所以我们今天的博客就把注解的东西给系统的介绍一下,当然我们会依托于具体的实例。
“注解”说白了就是存储数据的一种方式,如果注解单拎出来功能也就一般,如果将“注解”与Java的“反射机制”相结合,那么可以做的事情就多了。也就是说,你可以通过反射来读取“注解”提供的信息,然后来根据你的具体需求来做一些事情。当然,之前我们常用XML来为反射机制提供信息,不过“XML”的配置还是没有“注解”这种数据形式好管理,好维护,所以“注解”的地位还是比较重要的。
下方我们先聊一下“元注解”,然后在根据这些“元注解”来自定义注解,并使用Java的“反射机制”来读取各种类型的注解信息。
一、元注解
在本篇博客的第一部分,我们先来整体的看一下“元注解”,然后下方的内容再根据这些元注解进行展开。
1、@Target
使用方式:@Target(ElementType.CONSTRUCTOR)
@Target注解是比较重要的,Target的中文是“目标、位置”的意思,见名知意。@Target就用来声明我们创建的注解所放置的位置,也就是我们所创建的注解可以修饰什么样的元素。@Target的参数是一个ElementType的枚举,每个枚举项代表着一个位置。下方就是几个ElementType枚举比较常用的值:
TYPE: 类,如果@Target的参数是TYPE,那么我们创建的这个注解只能修饰类、接口、枚举等这些类型上。
FIELD: 字段修饰,如果我们的自定义注解是FIELD类型的话,那么我们的注解只能用来修饰类或者枚举的字段,也就是成员变量。
CONSTRUCTOR:构造器类型,该类型的“注解”只能修饰构造器。
METHOD:修饰“方法”的注解。
PARAMETER:修饰“方法”中的参数的注解。
LOCAL_VARIABLE: 修饰“局部变量”的注解。
当然,上面是简单一聊,下方会给出上述类型注解的具体实例。下面截图是ElementType中所有的选项以及每个枚举值的作用。具体如下所示,下方两个是1.8后新加的枚举项,如下所示:
2、@Retention
使用方式:@Retention(RetentionPolicy.RUNTIME)
上面是@Retention的使用方式,Retention的中文意思是“保留”,也就是说该元注解给出了“注解”的保留周期。@Retention也是接收一个枚举类型的参数,下方就是该枚举所包含的类型。下方的英文注释已经具体的给出了每个枚举项所对应的意思。
SOURCE:说明我们的注解只会留在我们的源码中,并不会被编译。
CLASS: 说明我们的注解会被编译成字节码存储到.class文件中,但不会在虚拟机中链接运行。
RUNTIME:这个就说明我们的注解会一直保留到程序的运行时,如果你想在运行时根据注解的信息通过反射机制做一些事情的话,那么必须得将我们的注解保留到这一阶段。
3、@Document与@Inherited
这两个注解就比较简单了,@Document说明将此注解包含在Javadoc中,而@Inherited则表示,该注解可以被子类继承。
上述的介绍可能会有些抽象,接下来我我们就根据实例,利用反射机制来操作相应类型的自定义注解。
二、测试用例介绍
下方截图是本篇博客所涉及Demo的目录以及主要的操作类。
AnnotationTracker:该类负责通过Java的“反射机制”来获取相应类型的注解的对象以及注解中的相关信息。在AnnotationTracker的类中,全是静态方法,静态方法传入的是相关注解修饰的Class。大体结构如下所示。
CE…Annotation:这些类是不同类型的注解,稍后我们会详细讨论。
TestClass:该类是注解所修饰的测试类。
Main:我们本Demo的测试用例的执行方法。
三、类型注解:@Target(ElementType.TYPE)
接下来,我们来看一下类型注解的创建与使用。下方内容我们下创建一个修饰类型的注解,然后再相关类中添加上该注解的修饰,最后使用Java的反射机制来获取相应的注解信息。
1、创建注解
首先创建我们的注解,具体步骤如下所示,选择Annotation后键入注解名点击回车即可。
下方代码段就是所创建注解中的详细内容。我们可以看出@Target元注解的参数是ElementType.TYPE类型的。也就是说明我们创建的这个注解是修饰类型的注解,可以作用域类、接口、枚举等类型。然后我们还看到@Retention的参数是RetentionPolicy.RUNTIME类型的,说明该注解一直被保留到运行时。
注解是使用@Interface来声明的,这与接口的什么类似。@Interface后方跟着的就是注解的名称,本注解的名称为CETypeAnnotation。其中有一个公有的(public)整数(int)类型的id属性。该属性的默认值是0,具体如下所示。
2、注解的使用
下方代码段是对上述注解的使用。因为上述创建的注解是ElementType.TYPE类型的,所以我们就用该注解来修饰我们创建的一个类,也就是下方的TestClass。在注解修饰时,我们给id设置了一个值,也就是下方的id = 10。
3、使用反射获取修饰类型注解的相关信息
接下来,我们就要在AnnotationTracker类中添加利用Java的“反射机制”来获取相应的TestClass类的注解的相关信息了,关键代码如下所示。trackTypeAnnotation()方法的参数是一个Class类型,然后可以通过Class的getAnnotation()方法来获取相应类中的注解对象。如下方的红框所示。
获取完相应的注解对象后,我们就可以获取到相应注解中的配置信息了。
4、测试用例以及测试结果
接下来我们就在Main方法中来调用AnnotationTracker类中的上述方法,并传入TestClass,如下所示。下方是其打印结果。
四、其他类型的注解
上述我们详细的聊了ElementType.TYPE类型的注解,接下来我们来看一下其他类型的注解,以及这些注解的使用方式。
1、@Target(ElementType.CONSTRUCTOR)
接下来我们来创建一个修饰构造器的注解。下方的CEConstructorAnnotation就是我们创建的用来修饰类构造器的注解。其中的value字段的默认值是一个空字符串。
2、@Target(ElementType.FIELD)
接下来我们就来创建一个修饰字段的注解,我们将该字段命名为CEFieldAnnotation,具体代码如下所示:
3、@Target(ElementType.METHOD)
下方是我们创建的修饰方法的注解,我们将其命名为CEMethodAnnotation,具体代码如下所示。
4、@Target(ElementType.PARAMETER)
下方是修饰方法中参数的注解,我们将其命名为,如下所示:
五、上述相关注解的使用
下方就是上述所定义的各种类型的注解的使用方式,各司其职。具体就不做过多赘述了。
六、使用反射机制获取不同类型的注解信息
之前我们已经聊了如何使用“Java”的反射机制来获取相关注解的信息,下方我们将会分别获取上述各种类型的注解的相关信息。下方代码主要是AnnotationTracker中的相关代码。
1、获取修饰构造器类型的注解信息
2、获取修饰方法和方法参数的注解信息
3、获取修饰字段的注解信息
4、测试用例以及输出结果
今天的博客就先到这儿吧,下篇博客仍然会更新Java相关的博客。
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #777777 }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }
span.s1 { color: #777777 }
span.s2 { color: #0326cc }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }
span.s1 { color: #777777 }
span.s2 { color: #0326cc }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }
span.s1 { color: #777777 }
span.s2 { color: #0326cc }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }
span.s1 { color: #777777 }
span.s2 { color: #0326cc }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #777777 }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }
span.s1 { color: #777777 }
span.s2 { color: #0326cc }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #777777 }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }
span.s1 { color: #777777 }
span.s2 { color: #0326cc }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #777777 }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco }
span.s1 { color: #777777 }
span.s2 { color: #0326cc }
Java编程之反射中的注解详解的更多相关文章
- java中的注解详解和自定义注解
一.java中的注解详解 1.什么是注解 用一个词就可以描述注解,那就是元数据,即一种描述数据的数据.所以,可以说注解就是源代码的元数据.比如,下面这段代码: @Override public Str ...
- Sping框架中的注解详解
传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点:1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文件 ...
- Bom和Dom编程以及js中prototype的详解
一.Bom编程: 1.事件练习: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...
- java学习(二)多态中成员变量详解
今天我总结了一下java多态中成员变量的赋值与调用 举一个我当初做过的小案例: class Fu{ int num; void show(){} } class Zi extends Fu{ //in ...
- Java基础13:反射与注解详解
Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...
- [转载]java中import作用详解
[转载]java中import作用详解 来源: https://blog.csdn.net/qq_25665807/article/details/74747868 这篇博客讲的真的很清楚,这个作者很 ...
- JAVA反射概念及使用详解(超详细)
JAVA反射概念及使用详解 一.什么是反射? 反射:框架设计的灵魂 框架:半成品软件.可以在框架的基础上进行软件开发,简化编码 反射:将类的各个组成部分封装为其他对象,这就是反射机制 好处: ...
- Java中日志组件详解
avalon-logkit Java中日志组件详解 lanhy 发布于 2020-9-1 11:35 224浏览 0收藏 作为开发人员,我相信您对日志记录工具并不陌生. Java还具有功能强大且功能强 ...
- “全栈2019”Java第八十四章:接口中嵌套接口详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
随机推荐
- 读书笔记 effective c++ Item 46 如果想进行类型转换,在模板内部定义非成员函数
1. 问题的引入——将operator*模板化 Item 24中解释了为什么对于所有参数的隐式类型转换,只有非成员函数是合格的,并且使用了一个为Rational 类创建的operator*函数作为实例 ...
- 在ASP.NET Core中使用Apworks开发数据服务:对HAL的支持
HAL,全称为Hypertext Application Language,它是一种简单的数据格式,它能以一种简单.统一的形式,在API中引入超链接特性,使得API的可发现性(discoverable ...
- 前馈神经网络-反向传播(Back Propagation)公式推导走读
构造:输入神经元个数等于输入向量维度,输出神经元个数等于输出向量维度.(x1=(1,2,3),则需要三个输入神经元) 一 前向后传播 隐层:
- USACO Section 1.1-2 Greedy Gift Givers
Greedy Gift Givers 贪婪的送礼者 对于一群(NP个)要互送礼物的朋友,GY要确定每个人送出的钱比收到的多多少. 在这一个问题中,每个人都准备了一些钱来送礼物,而这些钱将会被平均分给那 ...
- php写流程管理
流程控制即某个人发起一个流程,通过一层一层审核,通过后,完成整个流程,若有一层审核未通过,中断整个流程.即结束! 比如请假流程: 某一员工发起一个请假流程,那么这个流程的节点人员即他的上级,上上级,上 ...
- 腾讯AlloyTeam正式发布Canvas魔幻线条 - curvejs
[原文链接] ## 写在前面 curvejs 中文读["克js"],是腾讯AlloyTeam打造的一款魔幻线条框架,让线条成为一名优秀的舞者,让线条们成为优秀的舞团,HTML5 ...
- 速成制作rpm包
FPM 由于很多软件在安装时需要编译,这会浪费不少的时间,为了提升部署效率,于是就想到制作rpm包.通常rpm包的制作是使用rpmbuild命令来制作,但是你需要知道它的语法,比较繁琐.这就用到了FP ...
- Android 性能优化——之控件的优化
Android 性能优化——之控件的优化 前面讲了图像的优化,接下来分享一下控件的性能优化,这里主要是面向自定义View的优化. 1.首先先说一下我们在自定义View中可能会犯的3个错误: 1)Use ...
- mina.net 梳理
LZ最近离职,闲着也是闲着,打算梳理下 公司做的是电商,CTO打算把2.0系统用java 语言开发,LZ目前不打算做java,所以 选择离职.离职前,在公司负责的最后一个项目 供应链系统. 系统分为 ...
- Linux环境下用户空间与内核空间数据的交换方式
在linux环境开发过程中,经常会需要在用户空间和内核空间之间进行数据交换. 介绍了 Linux 系统下用户空间与内核空间数据交换的几种方式 第一节:使用procfs实现内核交互简明教程(1) 第二节 ...