美文网首页
Java反射调用方法时捕获异常

Java反射调用方法时捕获异常

作者: 上帝与我同幻想 | 来源:发表于2018-04-25 22:13 被阅读0次

    问题描述

    反射调用方法时,方法内部抛出了自定义异常,但是无法在反射调用的时候捕获到抛出的自定义异常。
    代码如下:

    // 自定义异常
    public class MyException extends Exception {
        private static final long serialVersionUID = -7998753885990231365L;
        private String code;
        public MyException(String code, String message) {
            super(message);
                    this.code = code;
        }
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    }
    
    // 反射调用的方法
    public class MethodThrowMyException {
        public String throwMyException() throws MyException {
            throw new MyException("1", "自定义异常");
        }
    }
    
    // 捕获异常
    public class Invocation {
        public static void main(String[] args) {
            try {
                Class<?> c = Class.forName("myexception.MethodThrowMyException");
                Object o = c.newInstance();
                Method m = c.getMethod("throwMyException");
                m.invoke(o);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }catch(MyException e) {
                
            }
        }
    }
    
    这里会报错,Unreachable catch block for MyException. This exception is never thrown from the try statement body

    问题解决

    参考文章
    可以发现,JDK的API文档中,关于method.invoke的注释说明
    InvocationTargetException是用来处理内部方法抛出异常的

    图1

    继续看InvocationTargetException说明
    InvocationTargetException是一个受检查的异常,包含了由调用方法或构造函数引发的异常

    图2

    InvocationTargetException有两个方法可以获取方法内部抛出的异常

    图3
    因此修改捕获的方法
    public class Invocation {
        public static void main(String[] args) {
            try {
                Class<?> c = Class.forName("myexception.MethodThrowMyException");
                Object o = c.newInstance();
                Method m = c.getMethod("throwMyException");
                m.invoke(o);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
    
                // 方式一
                Throwable targetException = e.getTargetException();
                if(targetException instanceof MyException) {
                    System.out.println("捕获到自定义异常");
                    System.out.println("code:" + ((MyException) targetException).getCode());
                    System.out.println("message:" + targetException.getMessage());
                }
    
                // 方式二
                Throwable cause = e.getCause();
                if (cause instanceof MyException) {
                    System.out.println("捕获到自定义异常");
                    System.out.println("code:" + ((MyException) cause).getCode());
                    System.out.println("message:" + cause.getMessage());
                }
            }
        }
    }
    

    得到结果:

    java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at myexception.Invocation.main(Invocation.java:12)
    Caused by: myexception.MyException: 自定义异常
        at myexception.MethodThrowMyException.throwMyException(MethodThrowMyException.java:5)
        ... 5 more
    捕获到自定义异常
    code:1
    message:自定义异常
    
    可以看到方式一和方式二是一样的,那么getTargetExceptiongetCause有什么区别呢

    再次看到文档,这里指出getCause()是首选的方法,因此使用方式二就行了

    图4

    相关文章

      网友评论

          本文标题:Java反射调用方法时捕获异常

          本文链接:https://www.haomeiwen.com/subject/wdculftx.html