如何避免finally块中的throw子句

Man*_*ojP 7 java

我正在使用SonarQube来提高代码质量.我遇到了一个与异常处理有关的问题,它说从finally块中删除了throw子句.

} catch(Exception e) {
            throw new MyException("request failed : ", e);
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {               
                throw new MyException("failed to close server conn: ", e);
            }
        }
Run Code Online (Sandbox Code Playgroud)

根据我的理解,上面的代码看起来不错.如果我在最后删除throw子句并禁止异常,则此方法的调用者将无法知道服务器的状态.我不确定如果没有throw子句我们如何能够实现相同的功能.

Mar*_*nik 7

您最好的方法是使用自Java 7以来的Java 自动资源管理功能.如果由于某种原因您无法使用,那么下一个最好的方法是复制语法糖扩展到的内容:

public static void runWithoutMasking() throws MyException {
   AutoClose autoClose = new AutoClose();
   MyException myException = null;
   try {
       autoClose.work();
   } catch (MyException e) {
       myException = e;
       throw e;
   } finally {
       if (myException != null) {
           try {
               autoClose.close();
           } catch (Throwable t) {
               myException.addSuppressed(t);
           }
       } else {
           autoClose.close();
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

注意事项:

  • try如果关闭资源失败,您的代码会从块中吞下原始异常.最初的例外对于诊断来说肯定更重要;
  • 在上面的ARM习惯用法中,根据try-block中是否存在异常,关闭资源的方式也不同.如果try正常完成,则资源在任何try-catch块之外关闭,自然地传播任何异常.