- 准备一个简单的注解
package com.yusian.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 创建一个简单的注解SACheck * 该注解只能应用在方法上 * 注解保留到运行时 * 没有属性,只做标记用 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SACheck { }
- 准备一个简单的测试类
package com.yusian.annotation; import org.junit.Assert; /** * 计算器类,几个简单的方法做演示 */ public class Calculator { @SACheck public void add() { int ret = add(1, 2); String str = null; str.toLowerCase(); // 人为制造bug,检测测试效果 Assert.assertEquals(3, ret); } @SACheck public void sub() { int ret = sub(2, 1); ret = 1 / 0; // 人为制造bug,检测测试效果 Assert.assertEquals(1, ret); } @SACheck public void multiply() { int ret = multiply(2, 3); // 人为制造bug,检测测试效果 Assert.assertEquals(5, ret); } public void show() { System.out.println("show..."); } public int add(int a, int b) { return a + b; } public int sub(int a, int b) { return a - b; } public int multiply(int a, int b) { return a * b; } public int divide(int a, int b) { return a / b; } }
- 通过反射机制及注解的标记测试带SACheck注解的方法,将测试结果写入本地文件
package com.yusian.annotation; import java.io.*; import java.lang.reflect.Method; import java.util.Arrays; import java.util.concurrent.atomic.AtomicInteger; public class AnnoDemo { public static void main(String[] args) throws IOException{ // 通过Calculator类对象获取所有的成员方法 Calculator c = new Calculator(); Method[] declaredMethods = c.getClass().getDeclaredMethods(); // bug计数,这里本来可以定义一个int变量然后++就行了,但Lambda表达式中不支持修改外部变量 AtomicInteger errNum = new AtomicInteger(); // 准备一个IO写入流,检测出来的bug写入到文件中 BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt")); // 使用流进行筛选与遍历,将带有@SACheck注解的方法执行并检测出是否异常,如果有则写入到文件 Arrays.stream(declaredMethods).filter(method -> { return method.getAnnotation(SACheck.class) != null; }).forEach(method -> { try { method.invoke(c); } catch (Exception e) { try { bw.write("错误类型:" + e.getCause().getClass().getSimpleName()); bw.newLine(); bw.write("错误原因:" + e.getCause().getMessage()); bw.newLine(); bw.write("-------------------"); bw.newLine(); errNum.getAndIncrement(); } catch (IOException ioException) { ioException.printStackTrace(); } } }); bw.write("共检测出" + errNum + "个bug"); bw.newLine(); bw.flush(); bw.close(); } }
- 输出文件:bug.txt
错误类型:NullPointerException 错误原因:null - 错误类型:AssertionError 错误原因:expected:<5> but was:<6> - 错误类型:ArithmeticException 错误原因:/ by zero - 共检测出3个bug
注解、反射、文件IO流的综合应用
Leave a reply