Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在API的多个方法中集中异常处理_Java_Api_Exception_Error Handling - Fatal编程技术网

Java 如何在API的多个方法中集中异常处理

Java 如何在API的多个方法中集中异常处理,java,api,exception,error-handling,Java,Api,Exception,Error Handling,这是一个简单的Java8+问题,没有使用框架 我们正在为更高的层生成一个API,该层处理表示层和其他活动。我们已经和调用者达成了一致,所以他们很高兴收到我们抛出的一些特殊异常 同时,我们也在使用同一协议下的其他API,因此我们可以自己做一些事情并抛出异常,或者我们可以调用抛出约定异常的其他API。 目前,我们对调用的API引发的异常不做任何处理 问题是,我们在这个基础设施中处于处理抛出异常时的中间活动的最佳位置,因此我们需要捕获我们的异常和我们调用的异常所提供的异常;基本上是报告问题、引发系统控

这是一个简单的Java8+问题,没有使用框架

我们正在为更高的层生成一个API,该层处理表示层和其他活动。我们已经和调用者达成了一致,所以他们很高兴收到我们抛出的一些特殊异常

同时,我们也在使用同一协议下的其他API,因此我们可以自己做一些事情并抛出异常,或者我们可以调用抛出约定异常的其他API。 目前,我们对调用的API引发的异常不做任何处理

问题是,我们在这个基础设施中处于处理抛出异常时的中间活动的最佳位置,因此我们需要捕获我们的异常和我们调用的异常所提供的异常;基本上是报告问题、引发系统控制等,然后重新抛出原始异常,以便顶层保持现在的状态

在API的入口点类中,我们有大约300个方法:

public void method1 (arguments for method 1) {
...
}

...

public void method300 (arguments for method 300) {
...
}
我清楚地了解,我可以创建一种方法来集中异常管理中要采取的行动,例如:

public void myExceptionHandler (Exception e) {
    if (e instanceOf X) {
    } else if ...
    ...
    throw particularExceptionAccordingTheCase 
}
但我也会避免修改这300个方法

你知道如何在这300个方法中注入一个try-catch来将异常发送到myExceptionHandler,而不在每个方法中都添加一个try-catch吗

任何意见和想法都将不胜感激

-----------mprev0建议之后-------------------------------

我试过这种方法。它真的捕获了异常等等,但我不能重新抛出异常:我被迫捕获它,但这违背了将异常重新发送回顶层的要求。 虽然我可以抛出一个错误,但在第throw new FileNotFoundException()行出现了一个编译器错误

有什么想法吗

------------经过进一步挖掘,用装饰图案修复-------

以前的类实现不起作用,因为我无法更改方法的签名,需要重新抛出java.lang.Exception

使用decorator并在那里处理接口就可以实现这个技巧。 作为总结:

顶层类别:

public class TopLayer {
    public static void main (String[] args) {
        MiddleLayer m = new MiddleLayer();
        m.method1();
    }
}
底层类包含特定的API和一些实现,唯一有趣的是它包含java.lang.Exceptions,期望顶层完成这项工作。但是,我们在中间工作,我们将做这项工作:

public class MiddleLayer extends BottomLayer {

    public MiddleLayer () {
        final UncaughtExceptionHandler subclass = Thread.currentThread().getUncaughtExceptionHandler();
        Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, Throwable ex) {

                System.out.println("gotcha2!");
                // carry on with prior flow
                subclass.uncaughtException(thread, ex);
            }
        });

    }

}
通过这种方式,我可以获取system.out,并将java.lang.Exception传播到顶层

装饰师的灵感来自这里:


欢迎更多评论

您可以通过实现以下接口来解决此问题:

public class MyExceptionHandler implements Thread.UncaughtExceptionHandler {

    @Overrides
    public void uncaughtException(Thread t, Throwable e) {
            if (e instanceOf X) {
            } else if ...
            ...
            throw particularExceptionAccordingTheCase 
    }
}
然后将其与所有线程关联,如下所示:

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler())
这将配置异常处理程序以处理应用程序的所有线程中的所有未捕获异常

请注意,这仅适用于代码中尚未显式处理的异常,并且如果没有为某些特定线程配置其他处理程序(也可以为某些特定线程设置未捕获的异常处理程序)


编辑:正如@JBC所发现的,上述方法不适用于检查异常,因为我们被迫在uncaughtException方法中显式地捕获它们(请注意,我们是这样做的)。虽然如果我们只想重新抛出and的子类型,它将不会出现问题,但如果我们想使其工作,则需要进行一些调整-您可以在@JBC的问题中找到解释。

您还可以在当前API的基础上创建代理API,在代理中有一个调用处理程序方法,并将该方法放在try-catch块中


正如您在问题更新中所看到的,最终的解决方案是两种不同方法的组合,一方面是采用mprev0方法实现java.lang.Thread.UncaughtExceptionHandler,另一方面是添加装饰模式,以便能够重新引发运行时异常

到目前为止还没有其他的方法,所以我现在结束这个问题,并把它作为最完整的回答

有关UncaughtExceptionHandler的更多信息可以在Java文档中找到,但与往常一样,这里缺少示例,如下所示:

有关装饰图案用法的更多信息,请参见:

以及如何在此处使用操作异常:

在API的入口点类twitches中,我们有大约300个方法。请看一下@JBC Good job,了解如何使其适应已检查的异常,谢谢分享!我更新了我的答案,也包括了你的发现。BTW.如果我或任何其他答案已经解决了你的问题,请考虑点击复选标记。这向更广泛的社区表明,你已经找到了一个解决方案,并给回答者和你自己带来了一些声誉。当然,没有义务这样做,但这会很好:-)谢谢mprev0,这听起来是个不错的方法。让我花几个小时来处理这个,然后很快再回来。这需要一个装饰图案!您好JBC,谢谢您的反馈!抱歉,我忽略了捕获的异常也将由全局异常处理程序重新抛出的细节,我认为您可能只会抛出运行时异常,因为选中的异常迫使我们捕获它们。幸运的是你找到了这个问题的解决方案,谢谢分享,看起来不错!嗨,萨米尔,谢谢你的回答。我不熟悉代理API。我需要花一些时间阅读文档并进行一些测试,因为这看起来不仅是捕获异常的替代方法,而且也是添加附加功能的替代方法。任何例子都将受到赞赏,但不是必需的,因为我相信会找到一些。谢谢嗨,Sameer,我一直在做一些测试,很抱歉,我找不到合适的模型。我已经基本上检查了你提供的链接。实施的唯一途径是
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler())