1.在通过反射执行方法的时,如Method.invoke(),如果被反射执行的方法体抛出了Exception,这个异常会被包装成InvocationTargetException重新抛出,下面是jdk里面的源码:
- public Object invoke(Object obj, Object... args)
- ows <SPAN style="COLOR: #ff0000">IllegalAccessException</SPAN>, IllegalArgumentException,
- InvocationTargetException
- {
- ...........此处省略.....
- }
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
...........此处省略.....
}
比如反射方法里抛出了NullPointException,则Method.invoke方法抛出的是InvocationTargetException,而不是NullPointException,见下面的例子,此处抛出的就是InvocationTargetException。
但是InvocationTargetException太过于宽泛,在trouble shouting的时候,不能给人非常直观的信息,所以在处理反射方法异常的时候,我们需要把这个InvocationTargetException的targetException提取处理,重新抛出,因为这个才是对我们分析程序bug真正有帮助的异常:
- public class InvokeException {
- @SuppressWarnings("null")
- public void testException(){
- String nullString = null;
- nullString.toString();
- }
- public static void main(String[] args) throws Throwable {
- // TODO Auto-generated method stub
- try{
- InvokeException invokeException = new InvokeException();
- Method method = invokeException.getClass().getMethod("testException");
- method.invoke(invokeException);
- }catch (Exception e) {
- if(e instanceof InvocationTargetException){
- throw ((InvocationTargetException) e).getTargetException();
- }else{
- //doXXX()
- }
- }
- }
- }
public class InvokeException {
@SuppressWarnings("null")
public void testException(){
String nullString = null;
nullString.toString();
}
public static void main(String[] args) throws Throwable {
// TODO Auto-generated method stub
try{
InvokeException invokeException = new InvokeException();
Method method = invokeException.getClass().getMethod("testException");
method.invoke(invokeException);
}catch (Exception e) {
if(e instanceof InvocationTargetException){
throw ((InvocationTargetException) e).getTargetException();
}else{
//doXXX()
}
}
}
}
下一篇讲介绍如何利用Spring的aop来把程序中的check exception转化成自定义的uncheck exception.