我使用 SonarQube 来提高代码质量。我遇到了一个与异常处理相关的问题,它说从 finally block 中删除 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);
}
}
根据我的理解,上面的代码看起来不错。如果我在 finally 中删除 throw 子句并抑制异常,则此方法的调用者将无法知道服务器的状态。我不确定我们如何在没有 throw 子句的情况下实现相同的功能。
最佳答案
最好的方法是使用 Automatic Resource Management Java 的特性,从 Java 7 开始可用。如果由于某种原因你无法使用它,那么下一个最好的办法就是复制语法糖扩展成的内容:
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
block 中的原始异常。原始异常对于诊断肯定更重要; - 在上面的 ARM 习惯用法中,关闭资源的方式不同,具体取决于 try block 中是否已经存在异常。如果
try
正常完成,则资源在任何 try-catch block 之外关闭,自然传播任何异常。
关于java - 如何避免 finally block 中的 throw 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28187304/