当前位置: 首页 > 编程日记 > 正文

揭开Annotation的面纱

Annotation是Java5、6只后的新特征(中文称之为注解),并且越来越多的得到了应用,比如Spring、Hibernate3、Struts2、iBatis3、JPA、JUnit等等都得到了广泛应用,通过使用注解,代码的灵活性大大提高。这些都是使用别人定义的注解,一般注解的使用都是在一些基础框架或者类库中来定义的,因此很少见过有人自己去写一个注解出来并使用在程序中,因此注解的使用常常给人感觉很神秘,这就为你揭开注解的面纱。
注解的神秘之处在于:通过类似注释的方式,可以控制程序的一些行为,运行时的状态,可以为成员赋值,做配置信息等等,与常规编码思维大相径庭。只用别人定义好的注解是搞不懂这些问题的,要想真正知道注解内部的秘密,要自己定义注解,然后在程序中获取注解信息,拿到注解信息后,就可以为我所用了。
下面我简单演示下三类注解的用法:类注解、方法注解、字段(也称之域)注解的定义与适用,并看看如何获取注解的信息。
一、定义注解
package lavasoft.anntest; 

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 

/** 
* 类注解 

* @author leizhimin 2009-12-18 14:15:46 
*/
 

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
public @interface MyAnnotation4Class { 
        public String msg(); 
}
package lavasoft.anntest; 

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 

/** 
* 方法注解 

* @author leizhimin 2009-12-18 14:16:05 
*/
 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface MyAnnotation4Method { 
        public String msg1(); 

        public String msg2(); 
}
package lavasoft.anntest; 

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 

/** 
* 字段注解 

* @author leizhimin 2009-12-18 15:23:12 
*/
 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface MyAnnotation4Field { 
        public String commont(); 

        public boolean request(); 
}
二、写一个类,用上这些注解
package lavasoft.anntest; 

/** 
* 一个普通的Java类 
*/
 
@MyAnnotation4Class(msg = "测试类注解信息"
class TestClass { 
        @MyAnnotation4Field(commont = "成员变量的注解信息", request = true
        private String testfield; 

        @MyAnnotation4Method(msg1 = "测试方法注解信息1", msg2 = "测试方法注解信息2"
        public void testMethod() { 
                System.out.println("Hello World!"); 
        } 
}
三、测试注解
为了使用注解,需要通过反射获取注解的对象。通过注解对象来操作注解信息。
package lavasoft.anntest; 

import java.lang.reflect.Field; 
import java.lang.reflect.Method; 

/** 
* 测试类 

* @author leizhimin 2009-12-18 14:13:02 
*/
 
public class TestOptAnnotation { 
        public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException { 
                TestClass t = new TestClass(); 
                System.out.println("-----------MyAnnotation4Class注解信息---------"); 
                MyAnnotation4Class an4clazz = t.getClass().getAnnotation(MyAnnotation4Class.class); 
                System.out.println(an4clazz.msg()); 
                System.out.println("-----------MyAnnotation4Method注解信息---------"); 
                Method method = t.getClass().getMethod("testMethod"new Class[0]); 
                MyAnnotation4Method an4method = method.getAnnotation(MyAnnotation4Method.class); 
                System.out.println(an4method.msg1()); 
                System.out.println(an4method.msg2()); 
                System.out.println("-----------MyAnnotation4Field注解信息---------"); 
                Field field = t.getClass().getDeclaredField("testfield"); 
                MyAnnotation4Field an4field = field.getAnnotation(MyAnnotation4Field.class); 
                System.out.println(an4field.commont()); 
                System.out.println(an4field.request()); 
        } 
}
运行结果:
-----------MyAnnotation4Class注解信息--------- 
测试类注解信息 
-----------MyAnnotation4Method注解信息--------- 
测试方法注解信息1 
测试方法注解信息2 
-----------MyAnnotation4Field注解信息--------- 
成员变量的注解信息 
true 

Process finished with exit code 0
四、总结
看完上面的测试过程,Annotation已经不再神秘了,这里总结下自定义注解的使用方法:
1、自定义注解,注意注解的时空范围,简单说就是注解针对的目标(类、方法、字段),以及注解的时效(运行时、或者源码中有效)。
2、要获取注解的信息,必须通过Java的反射技术来获取Annotation对象,因为你除此之外没有别的获取注解对象的方法。
3、获取了注解对象,就可以调用注解的方法来获取相对应的值了。为基础框架所用。
4、当然,注解也可以没有定义成员,这样注解就成了一个标记符号了。
理解了这些,注解就不再神秘了。


本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/245407,如需转载请自行联系原作者

相关文章:

使用Nginx的proxy_cache缓存功能取代Squid

[文章作者:张宴 本文版本:v1.2 最后修改:2009.01.12 转载请注明原文链接:http://blog.s135.com/nginx_cache/]  Nginx从0.7.48版本开始,支持了类似Squid的缓存功能。这个缓存是把URL及相关组合当作Key,用…

oracle grant 权限

grant connect,resource,dba to user;CONNECT角色: --是授予最终用户的典型权利,最基本的 CREATE SESSION --建立会话 RESOURCE角色: --是授予开发人员的 CREATE CLUSTER --建立聚簇 CREATE …

技术沙龙 | TeaTalk 带你深度探索 SDN 网络技术再创新

越来越多的企业、行业和政府机关顺应企业数字化转型、云服务和国家政策等趋势将业务迁移上云。随着移动云的快速发展,对网络提供差异化的服务能力也提出了很多新的考验。大规模数据中心、虚拟化 SDN 网络技术及超融合软硬一体可编程设备在云网络的应用已成为行业发展…

利用windows 2003实现服务器群集的搭建与架设(一) NLB群集的创建与架设

实验场景:西安凌云系统高科技有限公司利用IIS搭建了一个WEB站点,域名为nlb.angeldevil.com。由于业务的逐渐增加,网站速度也越来越慢,而且经常出现故障,为公司的利益带来了很多的不便;公司决定使用两台WEB站…

nginx 反向代理,动静态请求分离,proxy_cache缓存及缓存清除

一,nginx反向代理配置 #tomcat 显然就是用户访问www.wolfdream.com(需要设置本地localhost,将www.wolfdream.com指向nginx所在IP)的时候(或将www.wolfdream.com直接写在nginx所在的IP地址),将请求转到到后台的tomcat服务器,即127.…

深度强化学习的前景:帮助机器掌控复杂性

作者:数据实战派 来源:数据实战派深度强化学习,即机器通过测试其行为后果来学习的方法,是人工智能最有前途和影响力的领域之一。它将深度神经网络与强化学习结合在一起,可以通过训练实现多个步骤的目标。它是自动驾驶汽…

成绩转换(15)

#include<stdio.h> int main() {int n;char ch;while(scanf("%d",&n)!EOF){if(n>100||n<0) continue;if(n>90) chA;else if(n>80) chB;else if(n>70) chC;else if(n>60) chD;else chE;printf("%c\n",ch);} }转载于:https://ww…

pangolin最新版 v2.5.2.975

Pangolin是一款帮助渗透测试人员进行Sql注入测试的安全工具。 所谓的SQL注入测试就是通过利用目标网站的某个页面缺少对用户传递参数控制或者控制的不够好的情况下出现的漏洞&#xff0c;从而达到获取、修改、删除数据&#xff0c;甚至控制数据库服务器、Web服务器的目的的测试…

nginx 的proxy_cache才是王道

nginx 的proxy_cache才是性价比最高的缓存,我目前的配置是LiteSpeednginx,可以参考apachenginx将动态内容交给LiteSpeed或apache来处理,然后利用proxy_cache反向代理全部缓存在硬盘,变成静态内容,大家都知道nginx跑静态内容是有多厉害了吧,所以这样就可以小内存跑大PV.但是这样…

Android 占位符 %1$s %1$d

1、整型&#xff0c;比如“我今年23岁了”&#xff0c;这个23是整型的。在string.xml中可以这样写&#xff0c;<string name"old">我今年%1$d岁了</string> 在程序中&#xff0c;使用 [java] view plaincopy String sAgeFormat getResources().getStrin…

谁说技术男不适合养猫!90后程序员2天做出猫咪情绪识别软件

整理 | 王晓曼出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;9月1日&#xff0c;一则关于#程序员2天做出猫咪情绪识别软件#的话题登上微博热搜&#xff0c;参与阅读的人数达到了8218.1万&#xff0c;讨论次数1.3万&#xff0c;引发网友们的热议。高手在民间&#…

符合RESTful的接口规范

把api放在专属域名下&#xff0c;要带版本号 api的url中应该只有名词&#xff0c;和数据库的表或文档资源相对应&#xff1b;对资源&#xff08;collection&#xff09;的具体操作类型则由http方法动词表示 &#xff08;安全性&#xff1a;不改变资源状态&#xff0c;类似只读&…

Nginx proxy_cache 使用示例

原文出处&#xff1a;http://blog.chenlb.com/2010/04/nginx-proxy-cache.html 动态网站使用缓存是很有必要的。前段时间使用了 nginx proxy_stroe 来保存静态页面&#xff0c;以达到缓存的目的。当然 proxy stroe 用来做缓存是不够好的方案。 缓存这一块当然还有 squid 之类的…

Lync 小技巧-49-Lync 自动备份-批量管理-用户(免费视频)

自从2010年开始&#xff0c;自从Lync Server 2010开始&#xff0c;我都在研究Lync 自动备份和批量管理用户&#xff0c;当年都做成功&#xff0c;做标准过&#xff0e;不过都是图片&#xff0c;未写博客&#xff0c;为什么呢?有可能你有这样那样的假设&#xff0c;但是今天可以…

数学很差的人能当程序员吗?

【CSDN 编者按】作者在大学时代受《程序员》杂志的启发&#xff0c;从数学专业投身计算机编程&#xff0c;毕业后进入软件开发行业。过去9年&#xff0c;他去过大厂敲代码&#xff0c;也曾在创业公司带过团队&#xff0c;一直从事“下一代”软件技术的研发&#xff0c;对于网上…

Nginx 学习笔记(六)引入线程池 性能提升9倍

原文地址&#xff1a;https://www.cnblogs.com/shitoufengkuang/p/4910333.html 一、前言 1、Nignx版本&#xff1a;1.7.11 以上 2、NGINX采用了异步、事件驱动的方法来处理连接。这种处理方式无需&#xff08;像使用传统架构的服务器一样&#xff09;为每个请求创建额外的专用…

Nginx源代码分析 - 日志处理

我看Nginx源代码的时候&#xff0c;感觉整个系统都在传递log指针。log在nginx里是比较关键的。日志和内存分配是最基础的两个起点代码&#xff0c;最好是在自己写的程序框架中早点完善并实现。以免未来要用大量的精力调整。1. 日志的源代码位置日志的源代码在src/code/ngx_log.…

strom.yaml配置

2019独角兽企业重金招聘Python工程师标准>>> 配置storm.yaml storm发行版在conf/storm.yaml包含了一些配置信息。你可以在这里看到默认配置。storm.yaml里面的配置比default.xml的优先级要高&#xff0c; 下面是要运行storm集群所必须的配置: 1. storm.zookeeper.se…

用 Python 快速制作海报级地图

作者&#xff1a;费弗里 来源&#xff1a;Python大数据分析 1 简介 基于Python中诸如matplotlib等功能丰富、自由度极高的绘图库&#xff0c;我们可以完成各种极富艺术感的可视化作品&#xff0c;关于这一点我在系列文章在模仿中精进数据可视化中已经带大家学习过很多案例了。 …

关于VS2012如何安装Windows Phone Toolkit

最近也是碰到很多问题&#xff0c;在编程的时候。这个问题是我遇到的比较棘手的一个&#xff0c;问了一堆人都说得很是模糊&#xff0c;最后还是琢磨出来了&#xff0c;深感欣慰。写下来以防以后忘记了怎么操作的&#xff0c;也期望能帮助到遇到同样问题的你。 首先让我先说了几…

论Oracle 11g数据库备份与恢复策略

11G中有个新特性&#xff0c;当表无数据时&#xff0c;不分配segment&#xff0c;以节省空间解决方案&#xff1a;1、insert一行&#xff0c;再roolback就会产生segment了该方法是在空表中插入一行数据&#xff0c;再删除&#xff0c;就会产生segment。则在数据库导出时可以导出…

使Apache实现gzip压缩

众所周知&#xff0c;在HTTP1.1中支持gzip压缩&#xff0c;这样可以缩小页面的容量从而加快页面的显示速度。可以使用常用HTTP抓包工具来检测一下你的站点是否开始了gzip压缩。 Apache默认的http.conf配置文件中没有开启gzip压缩&#xff0c;apache1.3.x可以用mod_gzip进行优化…

脸书 AI 识别误将黑人标记为「灵长类动物」

整理 | 禾木木 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 最近&#xff0c;Facebook用户在观看一段以黑人为主角的视频时&#xff0c;会看到一个自动生成的提示&#xff0c;询问他们是否愿意“继续观看灵长类动物的视频”。 视频的内容其实是几个黑人和警察发…

Forefront for OCS2007之部署

1. 前提准备①OCS服务器②创建一个域账户&#xff0c;用于Forefront IM通告。帐户还将用于运行 ForefrontRTCProxy 服务用来截取来自 Office Communications Server SIP 通信进行扫描。此帐户必须满足以下要求&#xff1a;该帐户必须被为ForefrontRTCProxy服务授予 “ 运行为服…

Memcached在大型网站中应用

memcached是一个高性能的分布式的内存对象缓存系统&#xff0c;通过在内存里维护一个统一的巨大的hash表&#xff0c;它能够用来存储各种格式的数据&#xff0c;包括图像、视频、文件以及数据库检索的结果等。最初为了加速 LiveJournal 访问速度而开发的,后来被很多大型的网站采…

iOS开发-照片选择

本来想做个注册登录的表单的&#xff0c;想想还是先做个简单的头像选择&#xff0c;一般情况下不管是内部管理系统还是面向公众的互联网公司&#xff0c;注册登录是免不了的&#xff0c;用户头像上传是免不了的&#xff0c;尤其是企业用户&#xff0c;上传了自己的图片才感觉自…

打造一流创新环境:协作、开放、可持续

作者 | 微软亚洲研究院院长 周礼栋 毋庸置疑&#xff0c;人类是群居物种。早在两千多年前&#xff0c;亚里士多德便在其著述《政治学》里揭示了人类群居共利协作的趋向&#xff1a;个体组成家庭&#xff0c;家庭组成村落&#xff0c;村落组成城池&#xff0c;城池组成国家和社会…

Ansible源码解析 Inventory组概念

group.py 作者 煮酒品茶 一个组的Class&#xff0c;包含对外方法以及属性如下。 组做为inventory的子节点&#xff0c;会有嵌套组&#xff0c;组变量&#xff0c;组内主机&#xff0c;子组&#xff0c;父组的一些概念 [ name, hosts, vars, child_groups, parent_groups, depth…

Hadoop简要介绍

本文大部分内容都是从官网Hadoop上来的。其中有一篇介绍HDFS的pdf文档&#xff0c;里面对Hadoop介绍的比较全面了。我的这一个系列的Hadoop学习笔记也是从这里一步一步进行下来的&#xff0c;同时又参考了网上的很多文章&#xff0c;对学习Hadoop中遇到的问题进行了归纳总结。 …

超 40W 奖金池等你来战!第二届“长沙银行杯”腾讯云启创新大赛火热来袭!...

HEY&#xff01;你在等待一个机会提升自己的能力吗&#xff1f;现在机会来啦&#xff01;第二届“长沙银行杯”腾讯云启创新大赛如约而至&#xff01;现在&#xff0c;让更多人见证你的创新能力和新鲜想法第二届“长沙银行杯”腾讯云启创新大赛由长沙银行联合腾讯云、腾讯云启共…