知识大全 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     = / /     )    public static void travelThroughTime(Date des tination)

  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( Yoyodyne Propulsion Systems )    public class OscillationOverthruster

   一个使用实例

  结合上面所讲的 我们在这里建立一个简单的基于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 * /docs/guide/language/l *  * @author cleverpig * */import java util List;public class UsingBuil tInAnnotation         //食物类        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);                        

   开发者自定义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中的注解以及应用

Java中的注解以及应用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Annotation注解

知识大全 打算自学java入门书籍 有点迷茫 据说入门不适合先看java程式设计思想 希望能给我推荐一本比较易懂的书

打算自学java入门书籍有点迷茫据说入门不适合先看java程式设计思想希望能给我推荐一本比较易懂的书疯狂的java讲义我是学过C的,想学Java,求推荐书,java程式设计思想这书教入门吗?JAVA程

知识大全 Java多线程程序设计入门

Java多线程程序设计入门  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在Java语言产生前传

知识大全 Java多线程程序设计初步入门

Java多线程程序设计初步入门  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在Java语言产生

知识大全 Java开源项目Hibernate快速入门

Java开源项目Hibernate快速入门  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  其实H

知识大全 Java socket 入门编程实例

Javasocket入门编程实例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  例子是学习编程的

知识大全 Java web start入门

Javawebstart入门  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  下面是用最简单的He

知识大全 Java初学入门需掌握的30个概念

Java初学入门需掌握的30个概念  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!    基本概念 

知识大全 Java Web Start 入门(一)

JavaWebStart入门(一)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb

知识大全 Java2入门经典教程 11.2 管理线程[4]

Java2入门经典教程11.2管理线程[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nbs