java反射如何获取自定义异常信息
问题引入
看一个例子:
package test;
public class Test2 {
public static void main(String[] args) {
test();
Count2 count = new Count2();
test(count);
}
//直接调用
public static void test(){
try {
Count2.count(10,0);
} catch (Exception e) {
System.out.println("直接调用获取取异常信息:"+e.getMessage());
}
}
//使用反射调用
public static void test(Object o) {
try {
o.getClass().getMethod("count",Integer.class,Integer.class).invoke(null,10,0);
}catch (Exception e){
System.out.println("直接调用获取取异常信息:"+e.getMessage());
}
}
}
class Count2{
public static void count(Integer i,Integer j) throws Exception {
try {
System.out.println(i/j);
}catch (ArithmeticException e){
//将真正的异常写入日志
//log.writer(e)
//抛出自定义异常
throw new Exception("运算非法:除数为零");
}
}
}
运行结果:
直接调用获取取异常信息:运算非法:除数为零
反射调用获取取异常信息:null
可见,使用反射去调用方法,无法获取自定义的异常信息,只会报null。
原因分析
由上述代码,我们可以看到,反射调用的方法,有三个编译异常InvocationTargetException ,IllegalAccessException,NoSuchMethodException。
由于反射调用的方法,无法确定目标方法具体抛出的异常,jvm不能在编译期间确定方法的throws 类型,所以方法可能抛出的异常jvm也不能动态确定其类型,而统一抛出InvocationTargetException,而我们就可以通过这个异常去获取目标方法具体的异常。
解决
我们可以利用InvocationTargetException来获取自定义异常,修改上述代码如下:
//使用反射调用
public static void test(Object o) {
try {
o.getClass().getMethod("count",Integer.class,Integer.class).invoke(null,10,0);
} catch (IllegalAccessException e) {
//写入日志
} catch (InvocationTargetException e) {
Throwable t = e .getTargetException();
System.out.println("反射获取异常信息:"+t.getMessage());
//写入日志
} catch (NoSuchMethodException e) {
//写入日志
}
}
运行结果:
直接调用获取取异常信息:运算非法:除数为零
反射获取异常信息:运算非法:除数为零