注解

  • 定义一个注解
public @interface MyAnno {
}
  • 将注解遍历再反编译
    • 注解的本质上就是一个接口,该接口默认继承Annotation接口
public interface MyAnno extends java.lang.annotation.Annotation{

}
  • 属性:接口中的抽象方法
    • 属性的返回值类型只能是下列的类型
      • 基本数据类型
      • String
      • 枚举
      • 注解
      • 以上类型的数组
public @interface MyAnno {
    String name();
}
  • 定义了属性在使用的时候需要给属性赋值
@MyAnno(name = "hello world")
public class Worker {
}
  • 如果有默认值,则在使用的时候可以不赋值
public @interface MyAnno {
    String name() default "chenminglin";
}
@MyAnno
public class Worker {
}
  • 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,指定定义即可
public @interface MyAnno {
    String value();
}
@MyAnno("chenminglin")
public class Worker {
}
  • 元注解(用于描述注解的注解)
    • @Target:描述注解能够作用的位置
      • TYPE:可以作用于方法撒花姑娘
      • METHOD:可以作用于方法上
      • FIFLD:可以作用于成员变量上
    • @Retention:描述注解被保留的阶段
    • @Documented:描述注解是否被抽取到api文档中
    • @Inherited:描述注解是否被子类继承
@Target(value = {ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
@Documented
@Inherited
public @interface MyAnno1 {
}
  • 在程序中使用(解析)注解,获取注解中定义的属性值

  • 自定义注解

/**
 * 描述需要执行的类名,和方法名
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro {
    String className();
    String methodName();
}
  • Demo01.java
public class Demo01 {
    public void show(){
        System.out.println("demo01 -> show()");
    }
}
  • 使用注解
@Pro(className = "annoDemo.Demo01",methodName = "show")
public class ReflectTest {
    public static void main(String[] args) throws Exception {
        //1.获取改类的字节码文件对象
        Class<ReflectTest> reflectTestClass = ReflectTest.class;
        //2.获取上边的注解对象,其实就是在内存中生成了一个该注解接口的子类实现对象
        Pro annotation = reflectTestClass.getAnnotation(Pro.class);
        //3.调用注解对象定义的抽象方法,获取返回值
        String className = annotation.className();
        String methodName = annotation.methodName();

        //4.使用返回执行show方法
        Class aClass = Class.forName(className);
        Object o = aClass.newInstance();
        Method method = aClass.getMethod(methodName);
        method.invoke(o);
    }
}
  • Demo,使用注解编写一个框架,添加注解则可以输出哪些方法存在异常

  • 注解类

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Check {
}
  • 计算类,使用注解
/**
 * 计算器类
 */
public class Calculator {
    @Check
    public int add(){
        return 1 + 1;
    }

    @Check
    public int div() {
        return 1 / 0;
    }
}
  • 框架,检测添加注解的方法时候有异常
public class TestCheck {
    public static void main(String[] args)  throws Exception{
        //获取计算器class对象
        Class<Calculator> calculatorClass = Calculator.class;
        Calculator calculator = calculatorClass.newInstance();
        //获取所有的方法
        Method[] methods = calculatorClass.getMethods();
        //遍历所有方法
        for (Method method : methods){
            //判断方法时候有@Check注解
            if (method.isAnnotationPresent(Check.class)){
                try{
                    method.invoke(calculator);
                }catch (Exception e){
                    System.out.println("方法:"+method.getName()+" 出现异常 ---> " + e.getCause().getClass().getSimpleName());
                    System.out.println("异常原因:" + e.getCause().getMessage());
                }
            }
        }
    }
}
  • 控制台输出
方法:div 出现异常 ---> ArithmeticException
异常原因:/ by zero
posted @ 2022-10-18 21:04  youmo~  阅读(19)  评论(0编辑  收藏  举报