zoukankan      html  css  js  c++  java
  • java核心学习(十) 注解Annotation----上

    一、java的五个自带的注解

      @Override,方法重写的限定

      @Deprecated,标记已过时

      @SuppressWarnings,抑制编译器警告

      @SafeVararges,抑制堆污染警告

      @FunctionalInterface,标记函数式接口

    二、JDK的元Annotation

      元Annotation指 Annotation的Annotation,最根本的注解。在java8里共有六个元注解,其中五个·用于修饰其他注解的定义,另外一个用于定义java8新增的重复注解。

      1、 @Retention 用于指定被修饰的Annotation可以保留多长时间,有且仅有一个名为value的成员变量,value的值仅能为如下三种

        RetentionPolicy.CLASS 编译器把Annotation记录在class文件中,当运行java程序时,JVM不可以获取Annotation信息,不可以通过反射来获取Annotation信息,这也是value的默认值。

        RetentionPolicy.RUNTIME 编译器把Annotation记录在class文件中,可利用反射在运行时获取Annotation信息,JVM也可以获取反射信息。

        RetentionPolicy.SOURCE 只保留在java源代码中,在编译为class文件中丢弃之。

      2、 @Target 用于指定被修饰的Annotation能用于修饰哪些程序单元,也仅含有一个value成员变量,其允许的值如下

        ElementType.ANNOTATION_TYPE 指定该annotation只能用于修饰 Annotation

        ElementType.CONSTRUCTOR 指定该注解只能用于修饰构造器

        ElementType.FIELD 指定该注解只能修饰成员变量

        ElementType.LOCAL_VARIABLE 指定该注解只能修饰局部变量

        ElementType.METHOD 指定该注解只能修饰方法定义

        ElementType.PACKAGE 指定该注解只能修饰包定义

        ElementType.PARAMETER 指定该注解可以修饰参数

        ElementType.TYPE 指定该注解可以修饰类、接口(包括注解类型)或枚举定义。

      3、 @Documented 用于使用javadoc工具生成文档时加入注解,不赘述

      4、 @inherited 指定被该注解修饰的类具有继承性

    三、定义注解并使注解达到一定功能的实例

      实例一、定义一个Testable来标记哪些方法是可以测试的

        首先需要定义注解 @Testable ,定义注解就是定义注解的名字和上述的几个性质还有注解的内容(成员变量),注解本身只是对源代码添加一些特殊标记,注解本身并不会影响源代码,这些特殊标记可以被反射获取来编写注解的处理类。

        定义注解的代码:

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    //定义注解的持续时间为Runtime,定义注解的目标为Method
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface Testable {
        //该注解的功能为标记方法时候可被测试,不需要成员变量,仅仅只需要通过注解的有无来判断即可。
    }

        编写使用该注解的类

    public class MyTest {
        @Testable
        public static void m1(){
    
        }
    
        public static void m2(){
    
        }
        @Testable
        public static void m3(){
            throw new IllegalArgumentException("参数出错");
        }
        public static void m4(){}
        @Testable
        public static void m5(){
    
        }
    
        public static void m6(){
    
        }
        @Testable
        public static void m7(){
            throw new RuntimeException("程序业务出现异常");
        }
        public static void m8(){}
    
    }

        要想让上面MyTest类中的注解发挥作用,必须要编写注解的处理工具类,通过反射的方式来处理注解,这里用函数式接口来代替,真正处理注解的代码放在了main方法里

    public interface ProcessorTest {
    void process(String clazz) throws ClassNotFoundException;
    }

        main方法如下:

    import java.lang.reflect.Method;
    
    public class RunTests {
        public static void process(String clazz,ProcessorTest processorTest) throws ClassNotFoundException{
            processorTest.process(clazz);
        }
        public static void main(String[] args) throws ClassNotFoundException{
            process("MyTest", new ProcessorTest() {
                @Override
                public void process(String clazz) throws ClassNotFoundException{
                    int passed = 0;
                    int failed = 0;
                    for (Method m:Class.forName("MyTest").getMethods()
                         ) {
                        //判断方法是否使用了@Testable来修饰
                        if(m.isAnnotationPresent(Testable.class)){
                            try {
                                m.invoke(null);
                                passed++;
                            }
                            catch (Exception e){
                                System.out.println("方法"+ m + "运行失败,异常:"+e.getCause());
                                failed++;
                            }
                        }
                    }
                    System.out.println("共运行了:"+(passed+failed)+"个方法,其中:
    失败了:"+failed+"个,
    成功了:"+passed+"个");
                }
            });
        }
    }

        由于上面代码编译使用java7,所以无法使用lambda表达式。

        运行结果如下

    方法public static void MyTest.m3()运行失败,异常:java.lang.IllegalArgumentException: 参数出错
    方法public static void MyTest.m7()运行失败,异常:java.lang.RuntimeException: 程序业务出现异常
    共运行了:4个方法,其中:
    失败了:2个,
    成功了:2个
    
    Process finished with exit code 0
  • 相关阅读:
    MySQL数据模型
    Spring循环依赖
    @Autowired和@Resource区别
    Kafka概念
    阻塞队列
    线程池原理
    Spring AOP
    JVM 史上最最最完整深入解析(12000 字噢)
    Dubbo配置信息
    友情链接
  • 原文地址:https://www.cnblogs.com/Theshy/p/7505720.html
Copyright © 2011-2022 走看看