Java 注解原理

下面来看看Java中注解是如何实现的

创建注解类Inter:

Java 注解原理

 

创建测试类Test:

Java 注解原理

 

在程序第二句设置断点,可以看到:

Java 注解原理

 

可以看到,注解的实例是一个动态代理类的对象.

要想查看这个动态代理类,可以在代码中加

System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

添加系统代理,将其导出为class文件

Java 注解原理

 

可以看到如下两个文件:

Java 注解原理

 

反编译$Proxy1.class,如下:

Java 注解原理

 

可以看到,动态代理类是我们定义的注解实现类,反编译Inner.class,如下:

Java 注解原理

 

可以看到,注解接口继承了java.lang.annotation.Annotation, 通过查看源码,该类源码如下:

Java 注解原理

 

可以看到, 该类下的方法都被$Proxy1动态代理类实现了.

到此处,我们已经知道Inner注解(接口)是一个继承了Annotation接口的特殊接口,而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy1,该类就是Inner注解(接口)的具体实现类。

那么, 代理类是如何处理方法的调用的呢?

我们知道, 动态代理方法的调用最终会传递给绑定的InvocationHandler实例的invoke方法处理。我们可以看看$Proxy1的源码

Java 注解原理

 

其中语句调用了父类的成员变量,其父类为Proxy, 查看该成员变量,如下:

Java 注解原理

 

可以看到, h对象类型就是InvocationHandler接口的某个实现类

我们在Proxy类的构造方法处设置断点:

Java 注解原理

 

通过断点可以查看h具体是哪个对象:

Java 注解原理

 

可以看到, 该动态代理类为AnnotationInvocationHandler对象, 查看该类的invoke方法如下:

Java 注解原理

 

其中的memberValues变量是以方法名为key,以变量为value的, 如下:

Java 注解原理

 

那么,这个memberValues变量是从哪来的呢?

Java 注解原理

 

可以看到,其是在构造函数中进行设置的.

反编译我们的Test类,看到:

Java 注解原理

 

所以中间有一个类,负责创建代理对象AnnotationInvocationHandler, 其将变量从常量池中取出并创建map, 进而创建代理对象, 这个类就是 AnnotationParser, 在此不细说了, 感兴趣的可以自行断点调试查看.


总结

注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508577.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

myeclipse导入项目报错Target runtime Apache Tomcat v8.0 is not defined

今天想要查看一个现有的项目,本着最好使用原版本开发工具的奇怪想法,下载了一个myeclipse,在导入项目的时候报了一个错误 问题倒是挺明确的,就是项目需要的tomcat运行环境没有,有两种方法解决: 第一种方…

ExoPlayer用户手册

贴上原网址:https://google.github.io/ExoPlayer/guide.html 非完全翻译,有需要可以原网址自取,我发现网上也蛮多这个指导的翻译,可以去看看~ 开始啦!: ExoPlayer是一个开源的应用级媒体播放器&#xff0…

Android Studio查找功能(搜索功能)及快捷键

1、在当前窗口查找文本【CtrlF】 F3 向下查找关键字出现位置 ShiftF3 向上一个关键字出现位置 2、在当前工程内查找文本【CtrlShiftF】 先会弹出一个对话框,直接点击【find】,开始在整个工程内查找该字符串 查找结果如下: 3、查找类【C…

ZJU夏令营面试记录

首先记录一下这次夏令营面试。 1、进去后,圆桌会议,8个老师坐着。准备了6份简历简历表示不够,以后要多打几份。 2、首先,用英语介绍一下自己的专业(表示一脸懵逼) 3、说一下你这个暑假做了什么东西&…

Python的闭包

什么是闭包 #定义一个函数 def test(number): #在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包 def test_in(number_in): print("in test_in 函数, number_in is %d"%number_in) ret…

On the coexistence of transport protocols in data centers

论文信息:S. M. Irteza, A. Ahmed, S. Farrukh, B. N. Memon, and I. A. Qazi.On the coexistence of transport protocols in data centers. In Proceedings of IEEE ICC, 2014.数据中心传输协议的共存 摘要 云数据中心的出现直接导致了数据中心TCP(D…

Python中的特殊属性与方法

模块的特殊属性__doc__模块的说明文档__all__指明模块希望被使用的属性、类和方法__file__模块所在路径类的特殊属性__slots__限制类的实例允许添加的属性,是一个tuple元组类的特殊方法__new__(cls[, ...]) 1. __new__ 是在一个对象实例化的时候所调用的第一个方法 2. 它的第一…

如何做科研20171206

昨日听董大一席话,感触颇多,今日在此进行记录。(加粗字体为董大箴言) ① 关于看论文 董大问我你最近看了什么论文,我说,论文的题目没有记下来,只记得主要讲了什么。我以前一直以为一篇论文的阅…

contiki cooja仿真

最近在做contiki平台上的一些cooja仿真的东西,发现现在网上能学到的东西实在是很有限,现在在这里将我最近学到的一些东西做一下总结。 一、 关于运行的一般步骤: https://www.zhihu.com/question/48708549/answer/139050874 知乎上这个问…

MySQL指令笔记

-- 双中划线空格: 单行注释, 与#相同-- 链接数据库 mysql.exe -h localhost -P3306 -uroot -p-- 查看服务器的对外处理字符集 show variables like character_set%;-- 修改服务器认为的客户端数据的字符集为gbk;(单次访问有效) set character_set_client…

NS2:undefined reference to `xxx' collect2: error: ld returned 1 exit status

这个问题是没有链接。 刚开始先确认,头文件有没有导入。 以下是完整的提示信息错误,检查之后发现hdr_ant_pkt所在的头文件已经被导入;In function hdr_ant_pkt::access(Packet const*): cmu-trace.cc:(.text._ZN11hdr_ant_pkt6accessEPK6Pack…

6大设计原则之单一职责原则

单一职责原则 如果有一个用户管理类,类图如下 我想,任谁也能看的出这个接口设计的有问题,用户的属性和用户的行为没有分开,应该把用户的信息抽取成一个业务对象,把用户的行为抽取成一个业务对象,按照这个思路对类图进行修正,如下图所示 其实,在实际使用中我们更倾向于使用两个…

linux下Gnuplot的使用

压力是最好的老师。以前学不会Gnuplot只是因为不想学,

6大设计原则之里氏替换原则

面对对象中的继承 优点如下: 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性提高代码的重用性子类可以形如父类,但又异于父类提高代码的可扩展性,很多开源框架的扩展接口都是通过继承父类来实现的提高产品或项目的开放性 缺点如下: 继承是侵入性的.只要继承,就…

scikit-learn安装

安装找到一个简书版本,讲的挺好的,先贴网址 https://www.jianshu.com/p/26ab6c22051e 但是在安装过程中,遇见了问题,现在贴一下: numpy_quaternion-2018.5.17-cp36-cp36m-win32.whl is not a supported wheel on this …

6大设计原则之依赖倒置原则

依赖倒置原则的定义 依赖倒置原则的原始定义如下: High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions. 翻译过来,包含如下三层…

论文写作——paper Note

论文的一些细节: 1)数字10以下一般用英文单词,10以上用阿拉伯字母; 2)公式最后要有标点,逗号(后面跟where。。。)或者句号; 3)figure的caption尽量多写一点内…

6大设计原则之接口隔离原则

接口隔离原则的定义 什么是接口. 实例接口,比如定义了一个Person类,然后 Person p new Pserson(); 产生一个实例,Person类就是 p 的接口类接口,就是Java中使用 interface 定义的接口 什么是隔离 隔离要求将接口尽量细化,同时接口中的方法尽量少. 接口隔离原则的实现 比如…

6大设计原则之迪米特法则

迪米特法则的定义 迪米特法则也称为最少知识原则,一个对象应该对其他对象有最少的了解. 通俗的讲,一个类应该对自己需要耦合或调用的类知道的最少,被调用类的内部是如何复杂都和我没关系,我就知道你的这些public方法,我就调用这么多,其他的我一概不关心. 迪米特法则对类的低耦…

论文写作——origin画图

一 origin的安装 详见下面网址,内涵下载路径和破解方法。 http://www.ddooo.com/softdown/51005.htm 1. 下载origin 网址:https://thepcgo.com/origin-pro-8-0-free-download/ 2.下载破解相关压缩包 链接:https://pan.baidu.com/s/1LwA…