Java中的Annotation(2)----Annotation工作原理
上一篇文章已经介绍了如何使用JDK的三个标准Annotation,本文将介绍Annotation的原理,以及如何自定义Annotation,并利用Annotation来完成一些实际的功能。
定义Annotation
定义新的Annotation类型使用@interface关键字,这从一定意义上说明Annotation和接口的定义是有相似之处的。如下代码定义了一个Annotation
- //使用DK的元数据Annotation:Retention
- @Retention(RetentionPolicy.RUNTIME)
- //使用JDK的元数据Annotation:Target
- @Target(ElementType.METHOD)
- //定义一个标记注释,不包含任何成员变量,即不可传入元数据
- public @interface Testable{
- }
使用Annotation
定义了Annotation之后就可以在程序的任何地方使用该Annotation,对于Annotation的使用和public、final这样的修饰符很像,通常可以修饰类、方法、变量、接口等定义(默认情况下,Annotation用于修饰任何程序元素)。如下代码,就是使用了上面的Annotation修饰方法。
- public class MyTest {
- //使用@Testable标记注释指定该方法是可测试的
- @Testable
- public static void m1(){
- }
- public static void m2(){
- }
- //使用@Testable标记注释指定该方法是可测试的
- @Testable
- public static void m3(){
- throw new RuntimeException("Boom");
- }
- public static void m4(){
- }
- //使用@Testable标记注释指定该方法是可测试的
- @Testable
- public static void m5(){
- }
- public static void m6(){
- }
- //使用@Testable标记注释指定该方法是可测试的
- @Testable
- public static void m7(){
- throw new RuntimeException("Crash");
- }
- public static void m8(){
- }
- }
提取Annotation
一个类或者一个方法使用Annotation修饰之后需要通过反射来提取Annotation的信息。需要注意当一个Annotation类型被定义为运行时Annotation后该注释才是运行时可见的,当class文件被装载时被保存在class文件中的Annotation才会被虚拟机读取。下面代码就是将Annotation信息提取出来,根据这些信息进行相应的操作。在这里是如果某个方法被标记为可以测试的则调用这个方法。
- public class TestProcessor {
- public static void process(String clazz)throws ClassNotFoundException{
- int passed=0;
- int failed=0;
- //遍历obj对象的所有方法
- for(Method m :Class.forName(clazz).getMethods()){
- //如果包含@Testable标记注释
- if(m.isAnnotationPresent(Testable.class)){
- try{
- //调用m方法
- m.invoke(null);
- //passed加1
- passed++;
- }catch (Exception ex) {
- System.out.printf("方法"+m+"运行失败,异常"+ex.getCause()+"\n");
- failed++;
- }
- }
- }
- //统计测试结果
- System.out.println("共运行了:"+(passed+failed)+"个方法,其中:\n失败了:"+failed+",个,\n成功了:"+passed+"个!\n");
- }
- }
其中程序的主程序如下
- public class RunTests {
- public static void main(String[] args) throws Exception{
- //处理Mytest类
- TestProcessor.process("annotation.MyTest");
- }
- }
运行结果如下
工作原理
上面仅仅是一个简单地Annotation的使用,更复杂一些的Annotation与上面的这个例子原理是一样的,只不过相应的逻辑判断以及涉及到的Annotation中的内容较为复杂而已。但是核心的部分就是借助一个操作类通过反射的方式提取Annotation信息,进行操作,简而言之:无反射,不注释(Annotation)。
Java中的Annotation(2)----Annotation工作原理的更多相关文章
- 浅谈Java中的System.gc()的工作原理
很多人把Java的“效率低下”归咎于不能自由管理内存,但我们也知道将内存管理封装起来的好处,这里就不赘述. Java中的内存分配是随着new一个新的对象来实现的,这个很简单,而且也还是有一些可以“改进 ...
- 关于java中的hashcode和equals方法原理
关于java中的hashcode和equals方法原理 1.介绍 java编程思想和很多资料都会对自定义javabean要求必须重写hashcode和equals方法,但并没有清晰给出为何重写此两个方 ...
- 【java】详解java中的注解(Annotation)
目录结构: contents structure [+] 什么是注解 为什么要使用注解 基本语法 4种基本元注解 重复注解 使用注解 运行时处理的注解 编译时处理的注解 1.什么是注解 用一个词就可以 ...
- 【转载:java】详解java中的注解(Annotation)
目录结构: contents structure [+] 什么是注解 为什么要使用注解 基本语法 4种基本元注解 重复注解 使用注解 运行时处理的注解 编译时处理的注解 1.什么是注解 用一个词就可以 ...
- 深入理解Java中的反射机制和使用原理!详细解析invoke方法的执行和使用
反射的概念 反射: Refelection,反射是Java的特征之一,允许运行中的Java程序获取自身信息,并可以操作类或者对象的内部属性 通过反射,可以在运行时获得程序或者程序中的每一个类型的成员活 ...
- Java中的注解是如何工作的?
自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Override,@Deprecated这样的注解.这篇文章中,我将向大家讲述 ...
- Java 线程池的介绍以及工作原理
在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.将需处理的任务的数量大 使用线程池的好处: 1. 降低资源消耗: 通过重复利用已创建的线程降低线程创建和销毁造成的消耗.2. 提高响应速度: ...
- Java web每天学之Servlet工作原理详情解析
上篇文章中我们介绍了Servlet的实现方式以及Servlet的生命周期,我们这篇文章就来介绍一下常用对象. 点击回顾:<Java Web每天学之Servlet的工作原理解析>:<J ...
- JUC之Java中的阻塞队列及其实现原理
在文章线程池实现原理 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中介绍了线程池的组成部分,其中一个组成部分就是阻塞队列.那么JAVA中的阻塞队列如何实现的呢? 阻塞队列,关键字是阻塞 ...
- Java并发--Java中的CAS操作和实现原理
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/CringKong/article/deta ...
随机推荐
- 【DFS】NYOJ-82 迷宫寻宝(一)-条件迷宫问题
[题目链接:NYOJ-82] #include<iostream> #include<cstring> using namespace std; struct node{ in ...
- 应用市场高速下载以及网页端调起APP页面研究与实现
Github博文地址,此处更新可能不是很及时. 好久没写博客了,好大一个坑.正好,最近刚做完应用市场的高速下载功能,便拿来填了这个坑. 话说产品为了增加用户量,提升用户活跃度以及配合推广,更坑爹的是看 ...
- ajax请求总是不成功?浏览器的同源策略和跨域问题详解
场景 码农小明要做一个展示业务数据的大屏给老板看,里面包含了来自自己网站的数据和来自隔壁老王的数据.那么自己网站的数据提供了 http://xiaoming.com/whoami 这样的数据接口隔壁老 ...
- [Everyday Mathematics]20150122
设 $f:[0,1]\to [0,1]$. (1). 若 $f$ 连续, 试证: $\exists\ \xi\in [0,1],\st f(\xi)=\xi$. (2). 若 $f$ 单调递增, 试证 ...
- delete drop truncate
一.相同点 1 truncate.不带where子句的delete.drop都会删除表内的数据2 drop.truncate都是DDL语句(数据定义语言),执行后会自动提交 二.不同点 1trunca ...
- 数据库SQL Server与C#中数据类型的对应关系
ylbtech- .NET-Basic:数据库SQL Server与C#中数据类型的对应关系 数据库SQL SServer与C#中数据类型的对应关系 1.A,返回顶部 数据库 C#程序 int int ...
- UI篇--布局问题
1.android:layout_marginRight 不起作用解决方法 今天想在RelativeLayout的左右分别放上一个按钮, 左边按钮用marginLeft="10dp" ...
- codeforces 685B Kay and Snowflake 树的重心
分析:就是找到以每个节点为根节点的树的重心 树的重心可以看这三篇文章: 1:http://wenku.baidu.com/link?url=yc-3QD55hbCaRYEGsF2fPpXYg-iO63 ...
- Linux(CentOs)下安装Phantomjs + Casperjs
Linux(CentOs)下安装Phantomjs + Casperjs 是参照cnMiss's Blog http://ju.outofmemory.cn/entry/70691的博客进行安装的 1 ...
- 3D 矩阵旋转
如图,需要将点(向量) v(x, y, 0) 绕 z 轴旋转角度 θ,求旋转后的点(向量) v'(x', y', 0). 大概思路: 1. 将 v(x, y, 0) 分解, v(x, y, 0) = ...