如何避免finally块中的throw子句

时间:2015-01-28 08:01:37

标签: 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);
            }
        }

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

4 个答案:

答案 0 :(得分:6)

最好的方法是使用自Java 7以来可用的Java Automatic Resource Management功能。如果由于某种原因无法使用,那么接下来最好的事情就是复制语法糖扩展到的内容:

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();
       }
   }
}

注意事项:

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

答案 1 :(得分:2)

通常,finally块中的方法是清理'代码(关闭Connection等),用户不一定需要知道。

我为这些例外做的是吸收例外,但记录详细信息。

finally{
   try{
      connection.close();
   }catch(SQLException e){
      // do nothing and just log the error
      LOG.error("Something happened while closing connection. Cause: " + e.getMessage());
   }
}

答案 2 :(得分:1)

您收到警告,因为此代码在处理抛出的异常时可能会抛出异常。您可以使用尝试使用资源语法自动关闭资源。 Read more here

如果抛出“请求失败:”异常并且您无法关闭httpclient,则第二个例外是冒泡的异常。

答案 3 :(得分:0)

  

我不确定如果没有,我们如何才能实现相同的功能   抛出条款。

您可以不同地嵌套两个try块以获得相同的结果:

HttpClient httpClient = null; // initialize
try {
    try {
        // do something with httpClient
    } catch(Exception e) {
        throw new MyException("request failed : ", e);
    } finally {
        httpClient.close();
    }
} catch (IOException e) {               
    throw new MyException("failed to close server conn: ", e);
}