Java注解Annotation学习
学习注解Annotation的原理,这篇讲的不错:http://blog.csdn.net/lylwo317/article/details/52163304
先自定义一个运行时注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface HelloAnnotation {
String say() default "Hi";
}
然后在Main函数中解析注解
@HelloAnnotation(say = "Do it!")
public class TestMain {
public static void main(String[] args) {
HelloAnnotation annotation = TestMain.class.getAnnotation(HelloAnnotation.class);//获取TestMain类上的注解对象
System.out.println(annotation.say());//调用注解对象的say方法,并打印到控制台
}
}
HelloAnnotation注解的实例是jvm生成的动态代理类的对象。
这个运行时生成的动态代理对象是可以导出到文件的,方法有两种
- 在代码中加入
System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
- 在运行时加入jvm 参数
-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true
可以看到,我们自定义的注解HelloAnnotation是一个接口,而$Proxy1这个Java生成的动态代理类就是它的实现类
很明显,HelloAnnotation就是继承了Annotation的接口。再看第10行,flag字段中,我们可以看到,有个ACC_ANNOTATION
标记,说明是一个注解,所以注解本质是一个继承了Annotation的特殊接口。
而Annotation接口声明了以下方法。
package java.lang.annotation;
public interface Annotation {
boolean equals(Object var1);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
这些方法,已经被$Proxy1实现了。(这就是动态代理的机制)
无论是否了解动态代理,这里只需要明确一点,动态代理方法的调用最终会传递给绑定的InvocationHandler实例的invoke方法处理。
从上面不难看出,say方法最终会执行(String)super.h.invoke(this, m3, (Object[])null);
,而这其中的h对象类型就是InvocationHandler接口的某个实现类。
可以看到h对象是AnnotationInvocationHandler
的实例。让我们来看看该实现类的invoke方法。
可以看到,say方法的返回值是从一个Map中获取到的。这个map以key(注解方法名)—value(注解方法对应的值)存储TestMain类上的注解
那memberValues这个Map对象是怎么生成的,继续调试
通过方法调用栈找到memberValues的本源。
可以看到,memberValues是通过常量池获取到,return var2.getUTF8At(var3);
中的var3就是常量池中的序号。继续执行返回到parseMemberValue()方法。可以看到获取的就是我们定义在TestMain类上注解的say的值——“Do it!”。
小结
现在我们知道了HelloAnnotation注解(接口)是一个继承了Annotation接口的特殊接口,而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy1,该类就是HelloAnnotation注解(接口)的具体实现类。
注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。
Java注解Annotation学习的更多相关文章
- Java注解Annotation学习笔记
一.自定义注解 1. 使用关键字 @interface 2. 默认情况下,注解可以修饰 类.方法.接口等. 3. 如下为一个基本的注解例子: //注解中的成员变量非常像定义接口 public @int ...
- 深入学习JAVA注解-Annotation(学习过程)
JAVA注解-Annotation学习 本文目的:项目开发过程中遇到自定义注解,想要弄清楚其原理,但是自己的基础知识不足以支撑自己去探索此问题,所以先记录问题,然后补充基础知识,然后解决其问题.记录此 ...
- 深入JAVA注解-Annotation(学习过程)
JAVA注解-Annotation学习 本文目的:项目开发过程中遇到自定义注解,想要弄清楚其原理,但是自己的基础知识不足以支撑自己去探索此问题,所以先记录问题,然后补充基础知识,然后解决其问题.记录此 ...
- Java - 注解 (Annotation)
Java - 注解 (Annotation) 一.基本的 Annotation > 使用 Annotation 时要在其前面增加 @符号,并把该 Annotation 当成一个修饰符 ...
- Java注解Annotation(一)
Java注解Annotation(一)——简介 这一章首先简单介绍一下注解,下一章会给出一个注解应用的DEMO. 1. 元注解 元注解的作用是负责注解其他的注解. JDK1.5中,定义了4个标准的me ...
- Java注解(Annotation)详解
转: Java注解(Annotation)详解 幻海流心 2018.05.23 15:20 字数 1775 阅读 380评论 0喜欢 1 Java注解(Annotation)详解 1.Annotati ...
- Java注解Annotation与自定义注解详解
Java注解简介 开发中经常使用到注解,在项目中也偶尔会见到过自定义注解,今天就来探讨一下这个注解是什么鬼,以及注解的应用场景和如何自定义注解. 下面列举开发中常见的注解 @Override:用于标识 ...
- java注解Annotation
扯扯注解的蛋 为什么学习注解?学习注解有什么好处?学完能做什么? 1.能够读懂别人的代码,特别是框架相关的代码 2.让编程更加简洁,代码更加清晰 3.让别人高看你一眼 注解是java1.5引入的 概念 ...
- 秒懂,Java 注解 (Annotation)你可以这样学 - CSDN博客
https://blog.csdn.net/briblue/article/details/73824058 文章开头先引入一处图片. 这处图片引自老罗的博客.为了避免不必要的麻烦,首先声明我个人比较 ...
随机推荐
- ACM题目————还是畅通工程
Submit Status Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路 ...
- android的基础入门
一. A通信技术 1. 1G 仅限语音的蜂窝式通话标准 2. 2G (时分多路复用)数字语音传输技术和增加接收数据的功能 3. 3G 传输声音和数据的速度有很大的 提升 4. 4 ...
- 算法心得2:关于k个最小和问题的思考
问题描述如下: 有k个整数数组,各包含k个元素.在每个数组中取一个元素加起来,可以得到k^k个和.求这些和中最小的k个值(重复计算的算多次). 如果同时考虑这k个数组的取值情况,其复杂程度不言而喻,并 ...
- web简单连接html文件测试
Web工程: 条件: apache-tomcat-6.0.20(文件夹/7.0)=======位于E盘 标题:链接服务器 步骤: 第一步:打开apache-tomcat-6.0.20-bin-star ...
- if else 语句练习
一.if else 语句.
- 使用MSCOMM发送任意文件,还有一些注意事项
第一步:发送文件 FILE* pSENDFILE = _wfopen(m_edit_chosefile, _T("rb"));//以二进制打开待发送文件的的文件指针 fseek(p ...
- 2-Babel
一.什么是babel babel是一个源代码到源代码的转换器.比较广泛的用法就是可以把你写的符合 ECMAScript 6 标准的代码完美地转换为 ECMAScript 5 标准的代码,并且可以确保良 ...
- 中型企业的IT运维策略
如何建设一支能够解决问题.创造价值.有活力的.不断进取的IT运维团队,并带领这支团队?充分发挥这个团队的优势力量,是运维业务有效开展的关 键.运维策略是直接体现运维业务的经济价值所在.好的运维措施.方 ...
- javascript encodeURI和encodeURIComponent的比较
总结:encodeURI对除三种字符()之外的字符进行编码 encodeURIComponent对除两种字符之外的字符进行编码,保留字符会被转义 在进行SaaS前端开发的时候,大家经常会用到两个Jav ...
- JS中string对象的一些方法
原文地址(包含所有的string对象的方法): http://www.dreamdu.com/javascript/object_string/ string.slice(startPos,endP ...