- 浏览: 256399 次
- 性别:
- 来自: 福州
文章分类
最新评论
-
sflscar:
太好了,我搞了一下午,批量插入,第一个参数个数没对sql批量导 ...
redis pipe大数据量导入 -
赵青青:
那 entity.hbm.xml 文件中的主健策略怎么配置 ...
Hibernate 和 Access -
GapStar:
换成flash IconCellRenderer.as应该怎么 ...
DataGrid 中加入图标 -
binbinyouli:
不好意思。我把楼主注释掉得部分打开了。但是我看楼主有传递对象的 ...
Flex Flash 和JAVA 在Socket交互 -
binbinyouli:
不知道前两位评论人时怎么做得。我再做这个例子的时候出现了安全沙 ...
Flex Flash 和JAVA 在Socket交互
版权声明:本文可以自由转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
作者:cleverpig(作者的Blog:http://blog.matrix.org.cn/page/cleverpig)
原文:[http://www.matrix.org.cn/resource/article/44/44048_Java+Annotation.html]http://www.matrix.org.cn/resource/article/44/44048_Java+Annotation.html[/url]
关键字:Java,annotation,标注
摘要:
本文针对java初学者或者annotation初次使用者全面地说明了annotation的使用方法、定义方式、分类。初学者可以通过以上的说明制作简单的annotation程序,但是对于一些高级的annotation应用(例如使用自定义annotation生成javabean映射xml文件)还需要进一步的研究和探讨。涉及到深入annotation的内容,作者将在后文《Java Annotation高级应用》中谈到。
同时,annotation运行存在两种方式:运行时、编译时。上文中讨论的都是在运行时的annotation应用,但在编译时的annotation应用还没有涉及,
一、为什么使用Annotation:
在JAVA应用中,我们常遇到一些需要使用模版代码。例如,为了编写一个JAX-RPC web service,我们必须提供一对接口和实现作为模版代码。如果使用annotation对远程访问的方法代码进行修饰的话,这个模版就能够使用工具自动生成。
另外,一些API需要使用与程序代码同时维护的附属文件。例如,JavaBeans需要一个BeanInfo Class与一个Bean同时使用/维护,而EJB则同样需要一个部署描述符。此时在程序中使用annotation来维护这些附属文件的信息将十分便利而且减少了错误。
二、Annotation工作方式:
在5.0 版之前的Java平台已经具有了一些ad hoc annotation机制。比如,使用transient修饰符来标识一个成员变量在序列化子系统中应被忽略。而@deprecated这个 javadoc tag也是一个ad hoc annotation用来说明一个方法已过时。从Java5.0版发布以来,5.0平台提供了一个正式的annotation功能:允许开发者定义、使用自己的annoatation类型。此功能由一个定义annotation类型的语法和一个描述annotation声明的语法,读取annotaion 的API,一个使用annotation修饰的class文件,一个annotation处理工具(apt)组成。
annotation并不直接影响代码语义,但是它能够工作的方式被看作类似程序的工具或者类库,它会反过来对正在运行的程序语义有所影响。annotation可以从源文件、class文件或者以在运行时反射的多种方式被读取。
当然annotation在某种程度上使javadoc tag更加完整。一般情况下,如果这个标记对java文档产生影响或者用于生成java文档的话,它应该作为一个javadoc tag;否则将作为一个annotation。
三、Annotation使用方法:
1。类型声明方式:
通常,应用程序并不是必须定义annotation类型,但是定义annotation类型并非难事。Annotation类型声明于一般的接口声明极为类似,区别只在于它在interface关键字前面使用“@”符号。
annotation 类型的每个方法声明定义了一个annotation类型成员,但方法声明不必有参数或者异常声明;方法返回值的类型被限制在以下的范围: primitives、String、Class、enums、annotation和前面类型的数组;方法可以有默认值。
下面是一个简单的annotation类型声明:
清单1:
/** * Describes the Request-For-Enhancement(RFE) that led * to the presence of the annotated API element. */ public @interface RequestForEnhancement { int id(); String synopsis(); String engineer() default "[unassigned]"; String date(); default "[unimplemented]"; }
代码中只定义了一个annotation类型RequestForEnhancement。
2。修饰方法的annotation声明方式:
annotation 是一种修饰符,能够如其它修饰符(如public、static、final)一般使用。习惯用法是annotaions用在其它的修饰符前面。 annotations由“@+annotation类型+带有括号的成员-值列表”组成。这些成员的值必须是编译时常量(即在运行时不变)。
A:下面是一个使用了RequestForEnhancement annotation的方法声明:
清单2:
@RequestForEnhancement( id = 2868724, synopsis = "Enable time-travel", engineer = "Mr. Peabody", date = "4/1/3007" ) public static void travelThroughTime(Date destination) { ... }
B:当声明一个没有成员的annotation类型声明时,可使用以下方式:
清单3:
/** * Indicates that the specification of the annotated API element * is preliminary and subject to change. */ public @interface Preliminary { }
作为上面没有成员的annotation类型声明的简写方式:
清单4:
@Preliminary public class TimeTravel { ... }
C:如果在annotations中只有唯一一个成员,则该成员应命名为value:
清单5:
/** * Associates a copyright notice with the annotated API element. */ public @interface Copyright { String value(); }
更为方便的是对于具有唯一成员且成员名为value的annotation(如上文),在其使用时可以忽略掉成员名和赋值号(=):
清单6:
@Copyright("2002 Yoyodyne Propulsion Systems") public class OscillationOverthruster { ... }
3。一个使用实例:
结合上面所讲的,我们在这里建立一个简单的基于annotation测试框架。首先我们需要一个annotation类型来表示某个方法是一个应该被测试工具运行的测试方法。
清单7:
import java.lang.annotation.*; /** * Indicates that the annotated method is a test method. * This annotation should be used only on parameterless static methods. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test { }
值得注意的是annotaion类型声明是可以标注自己的,这样的annotation被称为“meta-annotations”。
在上面的代码中,@Retention(RetentionPolicy.RUNTIME)这个meta-annotation表示了此类型的 annotation将被虚拟机保留使其能够在运行时通过反射被读取。而@Target(ElementType.METHOD)表示此类型的 annotation只能用于修饰方法声明。
下面是一个简单的程序,其中部分方法被上面的annotation所标注:
清单8:
public class Foo { @Test public static void m1() { } public static void m2() { } @Test public static void m3() { throw new RuntimeException("Boom"); } public static void m4() { } @Test public static void m5() { } public static void m6() { } @Test public static void m7() { throw new RuntimeException("Crash"); } public static void m8() { } } Here is the testing tool: import java.lang.reflect.*; public class RunTests { public static void main(String[] args) throws Exception { int passed = 0, failed = 0; for (Method m : Class.forName(args[0]).getMethods()) { if (m.isAnnotationPresent(Test.class)) { try { m.invoke(null); passed++; } catch (Throwable ex) { System.out.printf("Test %s failed: %s %n", m, ex.getCause()); failed++; } } } System.out.printf("Passed: %d, Failed %d%n", passed, failed); } }
这个程序从命令行参数中取出类名,并且遍历此类的所有方法,尝试调用其中被上面的测试annotation类型标注过的方法。在此过程中为了找出哪些方法被 annotation类型标注过,需要使用反射的方式执行此查询。如果在调用方法时抛出异常,此方法被认为已经失败,并打印一个失败报告。最后,打印运行通过/失败的方法数量。
下面文字表示了如何运行这个基于annotation的测试工具:
清单9:
$ java RunTests Foo Test public static void Foo.m3() failed: java.lang.RuntimeException: Boom Test public static void Foo.m7() failed: java.lang.RuntimeException: Crash Passed: 2, Failed 2
四、Annotation分类:
根据annotation的使用方法和用途主要分为以下几类:
1。内建Annotation——Java5.0版在java语法中经常用到的内建Annotation:
@Deprecated用于修饰已经过时的方法;
@Override用于修饰此方法覆盖了父类的方法(而非重载);
@SuppressWarnings用于通知java编译器禁止特定的编译警告。
下面代码展示了内建Annotation类型的用法:
清单10:
package com.bjinfotech.practice.annotation; /** * 演示如何使用java5内建的annotation * 参考资料: * http://java.sun.com/docs/books/tutorial/java/javaOO/annotations.html * http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html * http://mindprod.com/jgloss/annotations.html * @author cleverpig * */ import java.util.List; public class UsingBuiltInAnnotation { //食物类 class Food{} //干草类 class Hay extends Food{} //动物类 class Animal{ Food getFood(){ return null; } //使用Annotation声明Deprecated方法 @Deprecated void deprecatedMethod(){ } } //马类-继承动物类 class Horse extends Animal{ //使用Annotation声明覆盖方法 @Override Hay getFood(){ return new Hay(); } //使用Annotation声明禁止警告 @SuppressWarnings({"deprecation","unchecked"}) void callDeprecatedMethod(List horseGroup){ Animal an=new Animal(); an.deprecatedMethod(); horseGroup.add(an); } } }
2。开发者自定义Annotation:由开发者自定义Annotation类型。
下面是一个使用annotation进行方法测试的sample:
AnnotationDefineForTestFunction类型定义如下:
清单11:
package com.bjinfotech.practice.annotation; import java.lang.annotation.*; /** * 定义annotation * @author cleverpig * */ //加载在VM中,在运行时进行映射 @Retention(RetentionPolicy.RUNTIME) //限定此annotation只能标示方法 @Target(ElementType.METHOD) public @interface AnnotationDefineForTestFunction{}
测试annotation的代码如下:
清单12:
package com.bjinfotech.practice.annotation; import java.lang.reflect.*; /** * 一个实例程序应用前面定义的Annotation:AnnotationDefineForTestFunction * @author cleverpig * */ public class UsingAnnotation { @AnnotationDefineForTestFunction public static void method01(){} public static void method02(){} @AnnotationDefineForTestFunction public static void method03(){ throw new RuntimeException("method03"); } public static void method04(){ throw new RuntimeException("method04"); } public static void main(String[] argv) throws Exception{ int passed = 0, failed = 0; //被检测的类名 String className="com.bjinfotech.practice.annotation.UsingAnnotation"; //逐个检查此类的方法,当其方法使用annotation声明时调用此方法 for (Method m : Class.forName(className).getMethods()) { if (m.isAnnotationPresent(AnnotationDefineForTestFunction.class)) { try { m.invoke(null); passed++; } catch (Throwable ex) { System.out.printf("测试 %s 失败: %s %n", m, ex.getCause()); failed++; } } } System.out.printf("测试结果: 通过: %d, 失败: %d%n", passed, failed); } }
3。使用第三方开发的Annotation类型
这也是开发人员所常常用到的一种方式。比如我们在使用Hibernate3.0时就可以利用Annotation生成数据表映射配置文件,而不必使用Xdoclet。
五、总结:
1。前面的文字说明了annotation的使用方法、定义方式、分类。初学者可以通过以上的说明制作简单的annotation程序,但是对于一些高级的 annotation应用(例如使用自定义annotation生成javabean映射xml文件)还需要进一步的研究和探讨。
2。同时,annotation运行存在两种方式:运行时、编译时。上文中讨论的都是在运行时的annotation应用,但在编译时的annotation应用还没有涉及,因为编译时的annotation要使用annotation processing tool。
涉及以上2方面的深入内容,作者将在后文《Java Annotation高级应用》中谈到。
六、参考资源:
·Matrix-Java开发者社区:http://www.matrix.org.cn
·http://java.sun.com/docs/books/tutorial/java/javaOO/annotations.html
·http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html
·http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html
·http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html
·作者的Blog:http://blog.matrix.org.cn/page/cleverpig
发表评论
-
redis pipe大数据量导入
2015-07-06 18:48 14170由于做性能测试,需要往redis中导出千万 ... -
Tongweb、Tomcat远程调试
2014-04-15 21:01 3567在开发过程中经常需要对布署在远程的程序进行跟踪测 ... -
JAVA中Integer 和 int 的比较
2012-06-17 15:04 808http://topic.csdn.net/u/2012060 ... -
java给图片加水印,文字水印
2010-10-09 10:03 1074package com.newland.bi.tt; i ... -
Struts+jsonplugin
2010-04-19 20:42 1062JSON官方文档 http://www.json.org/j ... -
jsp session 丢失
2010-04-19 20:37 23341.先访问a站点:http://192.168.18.2/te ... -
读取Properties的N种方法
2009-12-14 10:55 916如何读取资源文件:( ... -
Java正则表达式详解(上)
2009-03-28 10:24 925如果你曾经用过Perl或任 ... -
JAVA数据库基本操作指南
2009-03-28 10:04 944转自:http://www.qqread.com/java/2 ... -
不同Web主机上的Servlet之间数据对象的相互传输
2009-03-03 10:48 1248由于数据库服务器A和服务库服务器B之间存在着数据的交换,而WE ... -
与常用支付平台接口
2009-03-03 10:10 1337step-by-step集成阿里巴巴支付宝接口 http:// ... -
Java 6 RowSet 使用完全剖析(3)
2009-03-02 19:31 1168清单 24. 清单 23 中的代码执行结果 1 Tom Tom ... -
Java 6 RowSet 使用完全剖析(2)
2009-03-02 19:19 1952分页 由于 CachedRowSet 是 ... -
Java 6 RowSet 使用完全剖析(1)
2009-03-02 18:52 1815javax.sql.rowset 自 JDK 1.4 引入,从 ... -
关于log4j配置文档详解
2009-02-25 14:39 768一.参数意义说明输出级别的种类ERROR、WARN、INFO、 ... -
Log4j最简入门(很不错的Log4j入门)
2009-02-25 14:34 797<!--[if !supportLists]--> ... -
Java对象的序列化和反序列化实践
2008-12-29 14:38 875引:当两个进程在进行远 ... -
Java语言中的参数传递详解
2008-12-24 08:41 803和其它程序设计语言类 ... -
set map table list总结
2008-10-13 11:39 1379<转自>http://bluefishyong. ... -
多态的运用 实现java 数据类型判断
2008-09-03 12:54 2397package javaBasic;/** *//** * 用 ...
相关推荐
Java Annotation入门,本文初步告诉你怎么使用java anotatin
java annotation入门,java annotation入门,java annotation入门,java annotation入门
以下是JAVA annotation入门基础,新手朋友们可以过来参考下。希望对你有所帮助
java annotation 从JDK5.0后提供的功能。里面包含的实例,我是为了学习这个,所以放到这个上面作为中转。从别人博客里面摘取,博客地址里面附有。
Java+Annotation入门[定义].pdf
推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 14.Annotation(共10页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 15.输入输出(共41页).ppt 推荐优质Java课程 疯狂Java语言编程 Java...
推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 14.Annotation(共10页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 15.输入输出(共41页).ppt 推荐优质Java课程 疯狂Java语言编程 Java...
推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 14.Annotation(共10页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 15.输入输出(共41页).ppt 推荐优质Java课程 疯狂Java语言编程 Java...
推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 14.Annotation(共10页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 15.输入输出(共41页).ppt 推荐优质Java课程 疯狂Java语言编程 Java...
推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 14.Annotation(共10页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 15.输入输出(共41页).ppt 推荐优质Java课程 疯狂Java语言编程 Java...
推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 14.Annotation(共10页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 15.输入输出(共41页).ppt 推荐优质Java课程 疯狂Java语言编程 Java...
推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 14.Annotation(共10页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 15.输入输出(共41页).ppt 推荐优质Java课程 疯狂Java语言编程 Java...
推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 14.Annotation(共10页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 15.输入输出(共41页).ppt 推荐优质Java课程 疯狂Java语言编程 Java...
推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 14.Annotation(共10页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 15.输入输出(共41页).ppt 推荐优质Java课程 疯狂Java语言编程 Java...
推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 14.Annotation(共10页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 15.输入输出(共41页).ppt 推荐优质Java课程 疯狂Java语言编程 Java...
JDK5.0 Annotation 入门介绍 PDF
Java Annotation的初学者的入门样例,让读者更快的了解Annotation的用法和语法。
java-注解Java注解入门教程
Annotation在java的世界正铺天盖地展开,有空写这一篇简单的annotations的文章,算是关于Annotation入门的文章吧,希望能各位们能抛砖,共同学习