知识大全 Java Annotation入门
Posted 类型
篇首语:听闻少年二字,当与平庸相斥。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java Annotation入门相关的知识,希望对你有一定的参考价值。
基础学习教程:Java Annotation入门 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
摘要
本文针对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工作方式
在 版之前的Java平台已经具有了一些ad hoc annotation机制 比如 使用transient修饰符来标识一个成员变量在序列化子系统中应被忽略 而@deprecated这个javadoc tag也是一个ad hoc annotation用来说明一个方法已过时 从Java 版发布以来 平台提供了一个正式的annotation功能 允许开发者定义 使用自己的annoatation类型 此功能由一个定义annotation类型的语法和一个描述annotation声明的语法 读取annotaion的API 一个使用annotation修饰的class文件 一个annotation处理工具(apt)组成
annotation并不直接影响代码语义 但是它能够工作的方式被看作类似程序的工具或者类库 它会反过来对正在运行的程序语义有所影响 annotation可以从源文件 class文件或者以在运行时反射的多种方式被读取
当然annotation在某种程度上使javadoc tag更加完整 一般情况下 如果这个标记对java文档产生影响或者用于生成java文档的话 它应该作为一个javadoc tag 否则将作为一个annotation
三 Annotation使用方法
类型声明方式
通常 应用程序并不是必须定义annotation类型 但是定义annotation类型并非难事 Annotation类型声明于一般的接口声明极为类似 区别只在于它在interface关键字前面使用 @ 符号
annotation类型的每个方法声明定义了一个annotation类型成员 但方法声明不必有参数或者异常声明 方法返回值的类型被限制在以下的范围 primitives String Class enums annotation和前面类型的数组 方法可以有默认值
下面是一个简单的annotation类型声明
清单
/** * 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
修饰方法的annotation声明方式
annotation是一种修饰符 能够如其它修饰符(如public static final)一般使用 习惯用法是annotaions用在其它的修饰符前面 annotations由 @+annotation类型+带有括号的成员 值列表 组成 这些成员的值必须是编译时常量(即在运行时不变)
A 下面是一个使用了RequestForEnhancement annotation的方法声明
清单
@RequestForEnhancement( id = synopsis = Enable time travel engineer = Mr Peabody date =
B 当声明一个没有成员的annotation类型声明时 可使用以下方式 清单
/** * Indicates that the specification of the annotated API element * is preliminary and subject to change */ public @interface Preliminary
作为上面没有成员的annotation类型声明的简写方式
清单
@Preliminary public class TimeTravel
C 如果在annotations中只有唯一一个成员 则该成员应命名为value
清单
/** * Associates a copyright notice with the annotated API element */ public @interface Copyright String value();
更为方便的是对于具有唯一成员且成员名为value的annotation(如上文) 在其使用时可以忽略掉成员名和赋值号(=)
清单
@Copyright(
一个使用实例
结合上面所讲的 我们在这里建立一个简单的基于annotation测试框架 首先我们需要一个annotation类型来表示某个方法是一个应该被测试工具运行的测试方法
清单
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所标注
清单
public class Foo @Test public static void m () public static void m () @Test public static void m () throw new RuntimeException( Boom ); public static void m () @Test public static void m () public static void m () @Test public static void m () throw new RuntimeException( Crash ); public static void m () Here is the testing tool: import java lang reflect *; public class RunTests public static void main(String[] args) throws Exception int passed = failed = ; for (Method m : Class forName(args[ ]) 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的测试工具
清单
$ java RunTests Foo Test public static void Foo m () failed: java lang RuntimeException: Boom Test public static void Foo m () failed: java lang RuntimeException: Crash Passed: Failed
四 Annotation分类
根据annotation的使用方法和用途主要分为以下几类
内建Annotation——Java 版在java语法中经常用到的内建Annotation
@Deprecated用于修饰已经过时的方法
@Override用于修饰此方法覆蓋了父类的方法(而非重载)
@SuppressWarnings用于通知java编译器禁止特定的编译警告
下面代码展示了内建Annotation类型的用法
清单
package bjinfotech practice annotation;/** * 演示如何使用java 内建的annotation * 参考资料 * ml *
开发者自定义Annotation 由开发者自定义Annotation类型
下面是一个使用annotation进行方法测试的sample
AnnotationDefineForTestFunction类型定义如下
清单
package bjinfotech practice annotation;import java lang annotation *;/** * 定义annotation * @author cleverpig * *///加载在VM中 在运行时进行映射@Retention(RetentionPolicy RUNTIME)//限定此annotation只能标示方法@Target(ElementType METHOD)public @interface AnnotationDefineForTestFunction
测试annotation的代码如下
清单
package bjinfotech practice annotation;import java lang reflect *;/** * 一个实例程序应用前面定义的Annotation AnnotationDefineForTestFunction * @author cleverpig * */public class UsingAnnotation @AnnotationDefineForTestFunction public static void method () public static void method () @AnnotationDefineForTestFunction public static void method () throw new RuntimeException( method ); public static void method () throw new RuntimeException( method ); public static void main(String[] argv) throws Exception int passed = failed = ; //被检测的类名 String className= 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);
使用第三方开发的Annotation类型
这也是开发人员所常常用到的一种方式 比如我们在使用Hibernate 时就可以利用Annotation生成数据表映射配置文件 而不必使用Xdoclet
五 总结
前面的文字说明了annotation的使用方法 定义方式 分类 初学者可以通过以上的说明制作简单的annotation程序 但是对于一些高级的annotation应用(例如使用自定义annotation生成javabean映射xml文件)还需要进一步的研究和探讨
cha138/Article/program/Java/hx/201311/25569相关参考
Java中的注解以及应用 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Annotation注解
知识大全 打算自学java入门书籍 有点迷茫 据说入门不适合先看java程式设计思想 希望能给我推荐一本比较易懂的书
打算自学java入门书籍有点迷茫据说入门不适合先看java程式设计思想希望能给我推荐一本比较易懂的书疯狂的java讲义我是学过C的,想学Java,求推荐书,java程式设计思想这书教入门吗?JAVA程
Java多线程程序设计入门 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在Java语言产生前传
Java多线程程序设计初步入门 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在Java语言产生
Java开源项目Hibernate快速入门 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 其实H
Javasocket入门编程实例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 例子是学习编程的
Javawebstart入门 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 下面是用最简单的He
Java初学入门需掌握的30个概念 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 基本概念
JavaWebStart入门(一) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb
Java2入门经典教程11.2管理线程[4] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nbs