编程语言
首页 > 编程语言> > 用Java编写带有清除操作的catch块

用Java编写带有清除操作的catch块

作者:互联网

我找不到关于Java中catch块的任何建议,这些建议涉及一些清除操作,这些清除操作本身可能会引发异常.

经典的示例是stream.close()的示例,通常在finally子句中调用它,如果抛出异常,我们可以通过在try-catch块中调用它来忽略它,或者声明它被重新抛出.

但总的来说,我该如何处理以下情况:

public void doIt() throws ApiException { //ApiException is my "higher level" exception
  try {
    doLower();
  } catch(Exception le) {
    doCleanup(); //this throws exception too which I can't communicate to caller
    throw new ApiException(le);
  }
}

我可以做:

catch(Exception le) {
  try {
    doCleanup();
  } catch(Exception le1) {
  //ignore?
  //log?
  }
  throw new ApiException(le); //I must throw le
}

但这意味着我将必须进行一些日志分析以了解清理失败的原因.

如果我这样做了:

catch(Exception le) {
  try {
    doCleanup();
  } catch(Exception le1) {
    throw new ApiException(le1);
  }

结果导致丢失了将我带到第一拳的陷阱区的文件.

人们在这里使用哪些成语?

>在throws子句中声明较低级别的异常?
>清除操作期间是否忽略异常?

解决方法:

首先,确定您是否真的需要从finally块中抛出-请仔细考虑-在close()调用失败的情况下…好吧,记录下来就可以了-但是您的API的更高层真正可以做什么关于这个问题?因此,对于99%的情况,您将记录辅助数据库,然后重新抛出主数据库.

接下来,如果您确实需要抛出第二个异常,请确定导致第二个异常的各种原因是否重要.他们是很少见的.因此,将次要原因设置为主要原因(使用适当的构造函数或initCause()).

最后,如果必须抛出辅助节点,并保留辅助节点和主节点的完整堆栈跟踪,那么您将创建一个自定义Exception来处理这种情况.这很丑陋,因为您可能想从不同的父类派生.如果确实出现这种情况,我建议创建一个辅助类,该类能够填充目标异常的堆栈跟踪,从而根据两个异常生成有意义的跟踪(请确保对第二个异常使用缩进,因此嵌套的异常是容易拉开).

但大多数情况下,我建议您使用对数和重新抛出原语范式.专注于解决主要问题,次要问题通常会自行解决(这里的经典示例是IO异常,它使事情变得如此糟糕,以至于close()的调用也无法成功).

标签:exception,exception-handling,java
来源: https://codeday.me/bug/20191210/2099032.html