• Java 注解(Annoation)学习笔记


      1 Junit中的@Test为例:

       1.1 用注解(@Test)前

    private boolean isTestMethod(Method m) {  
            return   
                m.getParameterTypes().length == 0 &&   
                m.getName().startsWith("test") &&   
                m.getReturnType().equals(Void.TYPE);  
    }  

      用注解前(Junit4之前),Junit一般通过类似与上面的代码来获取一个测试类中的测试方法,通过反射获取到方法对象,然后再判断,其逻辑本质上是看一个测试方法应该为:以test开头、无参数、无返回值。 

      1.2 用注解(@Test)后

    @Test
    public void testName() throws Exception {
    }

         这里@Test的主要作用是标注testName这个方法为一个测试方法,起标注作用,可以算是一个marker annotation。和上面一样,为@Test标注的方法一样得是公有的、无参数、无返回值的,违反这两条规则,则会出现编译错误。

      1.2.1 获取测试方法流程

    1. 首先,获取待测试类所对应的Class对象
    2. 然后就可以获取其中的所有public方法所对应的Method数组。
    3. 遍历Method对象,获取每个Method对象
    4. 通过调用isAnnotationPresent(Test.class)方法,可以检查方法是否有名为Test的注解,
    5. 如果有这个注解,则为测试方法,调用Method对象的invoke()方法来执行这个方法。
    for (Method method : Foo.class.getDeclaredMethods()) {
        if (method.isAnnotationPresent(org.junit.Test.class)) {
            System.out.println("Method " + method + " has junit @Test annotation.");
        }
    }

          1.2.2 @Test的定义:    

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    public @interface Test {
    
        /**
         * Default empty exception
         */
        static class None extends Throwable {
            private static final long serialVersionUID = 1L;
    
            private None() {
            }
        }
    
        /**
         * Optionally specify <code>expected</code>, a Throwable, to cause a test method to succeed iff
         * an exception of the specified class is thrown by the method.
         */
        Class<? extends Throwable> expected() default None.class;
    
        /**
         * Optionally specify <code>timeout</code> in milliseconds to cause a test method to fail if it
         * takes longer than that number of milliseconds.
         */
        long timeout() default 0L;
    }

      先忽略其他细节不谈,@interface, 类似于Java中的class、enum、interface等。这个关键字声明隐含了一个信息:它是继承了java.lang.annotation.Annotation接口,并非声明了一个interface

      里面声明了两个成员:

    • expected,用于验证测试方法是否抛出预期的异常
    • timeout, 用于验证测试方法是否能在指定的时间内运行完。

        元注解

      java中元注解用来修饰注解的,自定义注解的时候可能用得到。大致有如下几种:

    1. @Document 表示这个注解或出现在使用它的目标位置对应的文档中。
    2. @Retention 保留策略
    3. @Target 注解适用目标
    4. @Inherited 默认情况下父类某个地方使用了一个注解,不会被继承到子类对应的地方,如果在注解上加上@Inherited,就会被继承到子类。

        注解保留策略

      如上面的@Retention(RetentionPolicy.RUNTIME)表示该注解会在运行时被保留,其中@Retention为元注解,元注解的作用就是负责注解其他注解。@Retention在这里控制了该注解的保留策略,可选值为:       

    1. SOURC在源代码中有效
    2. CLASS:在class文件中有效(即class保留,默认
    3. RUNTIME:在运行时有效(即运行时保留)

        注解适用范围

      @Target({ElementType.METHOD}) 表示该注解适用于方法,可选值有:

    1. TYPE, /** Field declaration (includes enum constants) */
    2. FIELD, /** Method declaration */
    3. METHOD, /** Parameter declaration */
    4. PARAMETER, /** Constructor declaration */
    5. CONSTRUCTOR, /** Local variable declaration */
    6. LOCAL_VARIABLE, /** Annotation type declaration */
    7. ANNOTATION_TYPE, /** Package declaration */
    8. PACKAGE

        注解作用

    1. 生成文档。这是最常见的,也是java 最早提供的注解。常用的有@see @param @return 等 
    2. 跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。
    3. 在编译时进行格式检查。如@Override放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。

        其他基本内置注释

      @Override 注释能实现编译时检查,你可以为你的方法添加该注释,以声明该方法是用于覆盖父类中的方法。如果该方法不是覆盖父类的方法,将会在编译时报错。例如我们为某类重写toString()方法却写成了tostring(),并且我们为该方法添加了@Override注释;

      @Deprecated 的作用是对不应该在使用的方法添加注释,当编程人员使用这些方法时,将会在编译时显示提示信息,它与javadoc里的@deprecated标记有相同的功能,准确的说,它还不如javadoc @deprecated,因为它不支持参数,

      @SuppressWarnings 与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数值都是已经定义好了的,我们选择性的使用就好了,参数如下:

     

    站在巨人的肩膀上,参考资料:

    http://www.blogjava.net/mlh123caoer/archive/2007/09/06/143260.html

    http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 

    http://www.cnblogs.com/mandroid/archive/2011/07/18/2109829.html

    http://www.cnblogs.com/mandroid/archive/2011/07/18/2109829.html

    http://www.cnblogs.com/phoebus0501/archive/2011/02/21/1960077.html

     

  • 相关阅读:
    linux 学习之七-部分ssh命令
    揭秘淘宝286亿海量图片存储与处理架构
    大型网站后台架构的演变
    Linux学习之六-Yum命令的使用
    res://ieframe.dll/acr_error.htm 纯手动解决方法
    VS2013启动项目调试的时候会启动本地IIS
    linux学习之(六)-主机名、网络IP的配置与查看
    deployment.yaml 带同步时区
    Deployment
    mysql.yaml
  • 原文地址:https://www.cnblogs.com/qinfanpeng/p/java_annotation.html
Copyright © 2020-2023  润新知