美文网首页
UndeclaredThrowableException的产生于

UndeclaredThrowableException的产生于

作者: 东阿 | 来源:发表于2019-06-17 15:47 被阅读0次

接上章
InvocationTargetException的产生与处理
有了上一章的 积累。
这次 的 UndeclaredThrowableException 的原因也基本 类似,也是 方法的执行过程中,方法没有被直接执行,
而是被通过 动态代理的方式 进行了执行。
上代码


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

class TestAException extends Exception {

    TestAException(String s) {
        super(s);
    }
}
interface IService {

    void foo() throws TestAException;
}

class ServiceImpl implements IService {

    @Override
    public void foo() throws TestAException {
        throw new TestAException("I test throw an checked Exception");
    }
}

class IServiceProxy implements InvocationHandler {
    private Object target;

    IServiceProxy(Object target){
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(target, args);
    }
}


public class AppTest {
    
    public static void main(String[] args) {
        IService service = new ServiceImpl();
        IService serviceProxy = (IService) Proxy.newProxyInstance(service.getClass().getClassLoader(),
            service.getClass().getInterfaces(), new IServiceProxy(service));
        try {
            serviceProxy.foo();
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

执行结果

java.lang.reflect.UndeclaredThrowableException
    at im.qingtui.pluto.$Proxy0.foo(Unknown Source)
    at im.qingtui.pluto.AppTest.main(AppTest.java:63)
Caused by: 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 im.qingtui.pluto.IServiceProxy.invoke(AppTest.java:46)
    ... 2 more
Caused by: im.qingtui.pluto.TestAException: I test throw an checked Exception
    at im.qingtui.pluto.ServiceImpl.foo(AppTest.java:33)
    ... 7 more

可以看到,异常 不仅 被 包裹了,还被 包裹了两层,具体的原因是
我们 使用 IServiceProxy 来代理 ServiceImpl。而实际执行的 代理 方法,有没有显示的 声明出,此方法会报TestAException错,动态代理执行的 时候,遇到"未知" 错误 就会将其 包装 为UndeclaredThrowableException。
而有因为 方法本身 是 通过反射 执行 的,所有 又包装了 一层 InvocationTargetException(原因见上一篇文章)

处理方案

修改代理方法 invoke

class IServiceProxy implements InvocationHandler {

    private Object target;

    IServiceProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        try {
            result = method.invoke(target, args);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
        return result;
    }
}

!!!请勿在生产环境直接使用
这样,代理方法执行的 时候 所抛出的 TestAException 是 原本 IService 的 foo() 本来就声明的 错误,不是"未知" 错误,那么 错误将会被 直接抛出,就能正常处理与识别了。
具体 到我们的 业务 逻辑 中 则 不能粗暴的 直接

catch (InvocationTargetException e) {
            throw e.getTargetException();
        }

这个方法 应该能解决一部分需求。但是

业务逻辑 千变万化
网上代码 不宜照抄

建议在异常 统一处理侧,再进行异常的解包,层层解。最后处理,好处是,异常的堆栈信息很好的保留下来,而不是贸然去除"不需要"的部分,不利于进行问题还原与问题追踪。

具体建议的处理方式 同上一章 相同,捕获 UndeclaredThrowableException获取其所包装的异常,在进一步处理

相关文章

  • UndeclaredThrowableException的产生于

    接上章InvocationTargetException的产生与处理有了上一章的 积累。这次 的 Undeclar...

  • UndeclaredThrowableException异常

    先来看看他的API说明 Thrown by a method invocation on a proxy inst...

  • 方差

    心中的情绪环绕周身影响着周围的事物被周围的事物影响喜悦 悲伤开心 紧张愤怒 失望平静 恐慌产生于情产生于景产生于心...

  • Java集合源码分析-Hashtable

    Hashtable产生于JDK 1.1,而HashMap产生于JDK 1.2,Hashtable基本已经弃用了,虽...

  • 茶道与跑步

    这两者有什么关系吗? 茶道产生于日本、剑道产生于日本、空手道、柔道、花道,为什么这些都产生于日本? 回想一下我们自...

  • Eyes

    你所看到的,正是你能看到的。 宇宙产生于100多亿年前,地球产生于45亿年前,智人产生于20万年前,人类文明经历几...

  • 剥削到底产生于资本,还是产生于官僚

    MKS的《资本论》,总是一再强调资本如何罪恶,剥削完全来自于资本对员工的压榨,那套说的天花乱坠的理论,仿佛说的头头...

  • 大脑的三种分类

    我们的大脑分为三部分,本能脑,情绪脑,理智脑。 本能脑产生于3.6亿年前,情绪脑产生于2亿年前,理智脑产生于250...

  • 理解产生于瞬间

    (59)理解产生于瞬间 前几日,我报名参加一个去西部支教的团队,草草地过了第一轮面试,第二轮面试我准备了很久,自以...

  • 《尼采全集》第2卷 摘录(1)

    生活毕竟不是凭道德想象出来的;它要的就是欺骗,它以欺骗为生……可不是吗? 理性产生于非理性,感觉产生于...

网友评论

      本文标题:UndeclaredThrowableException的产生于

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