1、结合反射使用
此种方法主要是在使用一些框架时,通过定义注解来实现对配置文件的读取,而不需要在读取本地配置文件
在程序使用(解析)注解:获取注解中定义的属性值
- 获取注解定义的位置的对象 (Class,Method,Field)
- 获取指定的注解
- getAnnotation(Class)
//其实就是在内存中生成了一个该注解接口的子类实现对象public class ProImpl implements Pro{public String className(){return "cn.itcast.annotation.Demo1";}public String methodName(){return "show";}}
- getAnnotation(Class)
- 调用注解中的抽象方法获取配置的属性值
代码示例
/*** 框架类*/@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface Pro {String className();String methodName();}@Pro(className = "cn.itcast.annotation.Demo1",methodName = "show")public class ReflectTest {public static void main(String[] args) throws Exception {/*前提:不能改变该类的任何代码。可以创建任意类的对象,可以执行任意方法*///1.解析注解//1.1获取该类的字节码文件对象Class<ReflectTest> reflectTestClass = ReflectTest.class;//2.获取上边的注解对象//其实就是在内存中生成了一个该注解接口的子类实现对象/*public class ProImpl implements Pro{public String className(){return "cn.itcast.annotation.Demo1";}public String methodName(){return "show";}}*/Pro an = reflectTestClass.getAnnotation(Pro.class);//3.调用注解对象中定义的抽象方法,获取返回值String className = an.className();String methodName = an.methodName();System.out.println(className);System.out.println(methodName);//3.加载该类进内存Class cls = Class.forName(className);//4.创建对象Object obj = cls.newInstance();//5.获取方法对象Method method = cls.getMethod(methodName);//6.执行方法method.invoke(obj);}}
2、简单测试框架
需求:测试计算器类中的方法是否出错;
常规思路,创建calculator类的实例,依次调用方法,看是否出错,此方法较为麻烦;
使用注解后,可通过反射的方法,获取calculator类的所有方法,同时通过判断是否有注解,进行测试,较为方便快捷
Calculator类
/*** 小明定义的计算器类*/public class Calculator {//加法@Checkpublic void add(){String str = null;str.toString();System.out.println("1 + 0 =" + (1 + 0));}//减法@Checkpublic void sub(){System.out.println("1 - 0 =" + (1 - 0));}//乘法@Checkpublic void mul(){System.out.println("1 * 0 =" + (1 * 0));}//除法@Checkpublic void div(){System.out.println("1 / 0 =" + (1 / 0));}public void show(){System.out.println("永无bug...");}}
check注解
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface Check {}
测试类
import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/*** 简单的测试框架** 当主方法执行后,会自动自行被检测的所有方法(加了Check注解的方法),判断方法是否有异常,记录到文件中*/public class TestCheck {public static void main(String[] args) throws IOException {//1.创建计算器对象Calculator c = new Calculator();//2.获取字节码文件对象Class cls = c.getClass();//3.获取所有方法Method[] methods = cls.getMethods();int number = 0;//出现异常的次数BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));for (Method method : methods) {//4.判断方法上是否有Check注解if(method.isAnnotationPresent(Check.class)){//5.有,执行try {method.invoke(c);} 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();}}
