需求
- 定义若干个方法,只要加了MyTest注解,就可以在启动时被触发执行
分析
- 定义一个自定义注解MyTest,只能注解方法,存活范围是一直都在
- 定义若干个方法,只要有@MyTest注解的方法就能在启动时被触发执行,没有这个注解的方法不能执行
package com.csdn.d8_annotation; import java.lang.annotation.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class AnnotationDemo4 { @MyTest public void test1() { System.out.println("======test1======"); } public void test2() { System.out.println("======test2======"); } @MyTest public void test3() { System.out.println("======test3======"); } /** * 启动菜单:有注解的才被调用。 * @param args */ public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { AnnotationDemo4 t = new AnnotationDemo4(); //a.获取类对象 Class<AnnotationDemo4> c = AnnotationDemo4.class; //b.提取全部方法 Method[] method = c.getDeclaredMethods(); //c.遍历方法,看是否有MyTest注解,有就跑它 for (Method method1 : method) { if (method1.isAnnotationPresent(MyTest.class)) { method1.invoke(t); } } } } @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @interface MyTest { } D:\Java\jdk-17\bin\java.exe ======test3====== ======test1======
简单的测试框架
- 当主方法执行后,会自动自行被检测的所有方法(加了Check注解的方法),判断方法是否有异常,记录到文件中
package com.csdn.annotation; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Method; /** * 简单的测试框架 */ public class TestCheck { public static void main(String[] args) throws IOException { /* Calculator calculator = new Calculator(); Class<Calculator> clazz = Calculator.class; Method[] m = clazz.getDeclaredMethods(); for (Method method : m) { if (method.isAnnotationPresent(Check.class)) { method.invoke(calculator); } } */ //1、创建计算器对象 Calculator cal = new Calculator(); //2、获取字节码文件对象 Class<Calculator> clazz = Calculator.class; //3、获取所有方法 Method[] me = clazz.getDeclaredMethods(); int number = 0;//出现异常的次数 BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt")); for (Method method : me) { //4、判断方法上是否有Check注解 if (method.isAnnotationPresent(Check.class)) { try { method.invoke(cal); } catch (Exception e) { //6、捕获异常 //记录到文件中 number++; 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(); } } } bw.write("本次测试一共出现" + number + "次异常"); bw.flush(); bw.close(); } } /** * 小明定义的计算器类 */ class Calculator { @Check public void add() { String str = null; str.toString(); 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("永无bug..."); } } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @interface Check { } D:\Java\jdk-17\bin\java.exe 1-0=1 1*0=0
小结
- 以后大多数时候,我们会使用注解,而不是自定义注解
- 注解的作用:第一个给编译器用,第二个给解析程序用
- 注解不是程序的一部分,可以理解为注解就是一个标签