注解

注解

注释和注解为都是为了说明程序的,注释是为了成程序员看的,注解是为了给计算机看的。注解是JDk1.5之后的特性,可以声明在包、类、字段、方法、局部变量、方法参数等前面用于说明解释。

1、注解作用分类

  1. 编写文档:通过代码的标识的注解生成文档(javadoc 生成doc文档)
  2. 代码分析:通过代码的标识的注解进行代码分析(使用反射)
  3. 编译检查:通过代码的标识的注解让编译器实现基本的检查(比如@Override,检查是够重写)

2、JDK预定义的注解

注解 描述
@Override 检查被该注解标注的方法是否是继承自父类,或者接口
@Deprecated 该注解标注的内容,表示已经过时
@SuppressWarnings 压制警告

3、自定义注解

格式

元注解
public @interface 注解名称{
	属性列表
}

注解的本质:注解本质上就是一个接口,该接口继承了java.lang.annotation.Annotation接口

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

注解的属性

由于注解本质上就是一个接口,接口中可以定义抽象方法,注解的属性就是注解中的抽象方法

  • 属性的返回值类型:基本数据类型、String、枚举、注解、或者以上类型的数组

  • 定义了一个属性,在使用时就必须为这个属性赋值

    • 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时可以不赋值(实际上是取了默认值)
    • 如果只有一个属性需要赋值,那么@myAnno(value = 12)可以简写为@myAnno(12)
    • 数组赋值时,使用大括号

    自定义注解:

    public @interface MyAnno {
        int value1();
        String value2() default "猪八戒";// 如果在使用注解时不赋值,那么就默认是“猪八戒”
        String[] value3();
    }
    

    使用自定义注解:

    public class Demo01Anno {
        @MyAnno(value1 = 1, value3 = "asdf")
        public static void method() {
        }
    }
    
  • 元注解:用于描述注解的注解

可以在自定义的注解前面加上元注解,主要有下面的元注解:

注解 描述
@Target 描述注解能够作用的位置
@Retention 描述注解被保留的阶段
@Documented 描述注解是否被抽取到API中
@Inherited 描述注解是否被子类继承
  • 元注解@Target的属性:只有一个属性value
    • 取值为ElementType.Type:表示这个被@Target描述的注解可以作用在类上
    • 取值为ElementType.METHOD:表示这个被@Target描述的注解可以作用在方法上
    • 取值为ElementType.FIELD:可以这个被@Target描述的注解作用在成员变量上
    • 可以取值为一个数组,包含这全部三个取值,那么就可以都作用与类,方法,成员变量
  • 元注解@Retention的属性:只有一个属性赋值,一般取值为RetentionPolicy.RUNTIME
    • 表示当前被描述的注解会保留到字节码文件中,并被JVM读取到
  • 元注解@Documented表示这个注解可以被抽取到回被抽取到API文档中
  • 元注解@Inherited:表示这个被描述的注解可以被子类继承

4、使用(解析)注解

5、注解的一个使用案例

需求:现在需要测试一个类的一些方法是否有异常,如果方法有异常,就记录到一个文件中,使用注解可以来实现。

  1. 创建一个要测试的类的对象
  2. 获得这个对象的Class对象
  3. 获得所有的方法
  4. 判断该方法是否有注解@Cheak()
  5. 有,就执行
  6. 执行的时候try catch,有异常就捕获,并记录到文件中

要测试的类:目测应该有两个异常

package cn.zhuobo.annotation;

public class Calculator {
    @Check
    public void add() {
        System.out.println("1 + 0 = " + (1 + 0));
    }
    @Check
    public void sub() {
        String s = null;
        String s1 = s.toString();
        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));
    }
}

实现的过程

package cn.zhuobo.annotation;


import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;

/*
    当主方法执行后,会检测类的所有方法,并且执行加了@Check注解的的方法,如果有异常,那么写入文件
 */
public class TestCheck {
    public static void main(String[] args) throws IOException {
        Calculator calculator = new Calculator();
        //获得所有的方法
        Class aClass = calculator.getClass();
        Method[] methods = aClass.getMethods();

        int count = 0;// 记录出现异常的次数
        FileWriter fw = new FileWriter("bug.txt");

        for (Method method : methods) {
            //对于每一个method,如果有check这个注解
            if(method.isAnnotationPresent(Check.class)) {
                //那么就执行
                try{
                    method.invoke(calculator);
                }catch (Exception e) {
                    // 如果有异常,那么就在这里记录到文件,也就是异常我是这么处理的

                    fw.write(method.getName() + "方法出异常了
");
                    fw.write("异常的名称:" + e.getCause().getClass().getSimpleName() + "
");
                    fw.write("异常的原因:" + e.getCause().getMessage() + "
");
                    count++;
                    fw.write("================================================
");

                }
            }
        }

        fw.write("本次一共出现" + count + "次异常
");
        fw.close();


    }
}
原文地址:https://www.cnblogs.com/zhuobo/p/10677016.html