Java注解

注解是JDK1.5后的新特性。

JDK预定义注解:

  • @Override(检测被注解的方法是否继承自父类)
  • @Deprecated(将被注解标记为已过时)
  • @SuppressWarnings(镇压警告,参数一般为all)

自定义注解:

  • 定义格式

    public @interface MyAnno {
    }
    
  • 本质,将编译后的class文件使用javap反编译得到

    public interface MyAnno extends java.lang.annotation.Annotation{  
    }
    

    所以,注解的本质就是接口!

注解的属性:

  • 属性的返回值类型限定为:

    1. 基本数据类型
    2. String
    3. 枚举
    4. 注解
    5. 以上类型的数组
  • 因为注解的本质是接口,在注解中定义的属性也就是方法,使用时给不同属性赋值可以看做为给方法一个返回值(格式:属性名=值)。

  • 当注解只有一个属性,且属性名为value时,使用注解赋值时可以直接赋值;

  • 定义注解时,可以使用default关键字设置默认值,没有设置默认值的属性使用时必须赋值;

    public @interface MyAnno {
        String name() default "zh";
    }
    
  • 属性的赋值实例

    @MyAnno(value = 1,per=Person.P1,anno2 = @MyAnno2,strs = {"aa","bb"})
    public class Worker {
    }
    

元注解:

  • 用于描述注解的注解
    1. @Target:注解作用的位置
    2. @Retention:注解保留的阶段
    3. @Documented:注解是否被抽取到api文档中
    4. @Inherited:注解是否被子类继承

注解的解析使用:

  • 使用注解定义类名和方法名,然后执行

    //定义的注解
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Pro {
        String className();
        String methodName();
    }
    //解析注解
    @Pro(className = "com.package.Demo",methodName = "show")
    public class Example {
        public static void main(String[] args) throws Exception {
            // 解析注解,获取当前的Class
            Class exampleClass = Example.class;
            // 获取上边的注解
            // 实际就是在内存中生成了一个该注解接口的子类实现对象
            Pro annotation = (Pro) exampleClass.getAnnotation(Pro.class);
            // 调用注解的方法获取设置的属性
            String className=annotation.className();
            String methodName=annotation.methodName();
    
            System.out.println(className);
            System.out.println(methodName);
    
    		// 获取到className后实例化Class对象
            Class aClass = Class.forName(className);
    		// 利用Class对象获取方法
            Method method = aClass.getMethod(methodName);
            // 利用Class对象生成一个实例
            Object obj=aClass.newInstance();
    		// 执行方法
            method.invoke(obj);
        }
    }
    

通过注解测试方法:

  • 注解定义

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface Check {
    }
    
  • 需要测试的类和方法

    public class Calculator {
        @Check
        public void add(){
            System.out.println("1+0="+(1+0));
        }
        @Check
        public void sub(){
            System.out.println("1-0="+(1-0));
        }
        @Check
        public void mul(){
            System.out.println("1*0="+(1*0));
        }
        @Check
        public void div(){
            System.out.println("1/0="+(1/0));
        }
        public void show(){
            System.out.println("show");
        }
    }
    
  • 实现代码

    public class TestChek {
        public static void main(String[] args) throws IOException {
            // 创建计算器对象
            Calculator calculator=new Calculator();
            // 获取字节码文件对象
            Class c=calculator.getClass();
            // 获取所有方法
            Method[] methods=c.getMethods();
            // 判断方法是否又check注解
            // 有就执行
            int num=0;//出现异常的次数
            BufferedWriter bw=new BufferedWriter(new FileWriter("bug.txt"));
            for (Method method : methods) {
                if(method.isAnnotationPresent(Check.class)){
                    try {
                        method.invoke(calculator);
                    } catch (Exception e) {
                        num++;
                        bw.write(method.getName()+"方法出异常了");
                        bw.newLine();
                        bw.write("异常的名称:"+e.getCause().getClass().getSimpleName());
                        bw.newLine();
                        bw.write("异常的原因:"+e.getCause().getMessage());
                        bw.newLine();
                        bw.write("-----------------");
                        bw.newLine();
    //                    e.printStackTrace();
                    }
                }
            }
            bw.write("一共"+num+"次异常");
            // 捕获异常
            bw.flush();
            bw.close();
        }
    }
    
原文地址:https://www.cnblogs.com/zhang-han/p/14393069.html