我正在使用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子句我们如何能够实现相同的功能。
答案 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
块中吞下原始异常。最初的例外肯定对诊断更重要; 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);
}