如何在java中的finally块中处理抛出异常(How to handle throw exceptions inside finally block in java)
在java中,不建议在try-chatch块的finally部分中抛出异常,因为隐藏了try或catch块中抛出的任何未处理的throwable的传播。 根据默认声纳配置文件,此做法是blocker级别违规。
声纳错误:从此finally块中删除此throw语句。
请考虑以下代码段。
例如:在finally块中关闭输入流,并在关闭流时处理可能发生的异常。
public void upload(File file) {
ChannelSftp c = (ChannelSftp) channel;
BufferedInputStream bis = new BufferedInputStream(file.toInputStream());
try {
String uploadLocation = Files.simplifyPath(this.fileLocation + "/" + file.getName());
c.put(bis, uploadLocation);
} catch (SftpException e) {
throw new IllegalTargetException("Error occurred while uploading " + e.getMessage());
} finally {
try {
bis.close();
} catch (IOException e) {
throw new UnsupportedOperationException("Exception occurred while closing Input stream " + e.getMessage());
}
}
}
如果您能够展示处理这些情况的传统方式,将不胜感激。
In java, it is not recommended to throw exceptions inside finally section in try-chatch block due to hide the propagation of any unhandled throwable which was thrown in the try or catch block. This practice is a blocker level violation according to default sonar profile.
Sonar Error: Remove this throw statement from this finally block.
Please consider the following code snippet.
e.g.: close input stream inside the finally block, and handle possible exceptions might be occurred when closing the stream.
public void upload(File file) {
ChannelSftp c = (ChannelSftp) channel;
BufferedInputStream bis = new BufferedInputStream(file.toInputStream());
try {
String uploadLocation = Files.simplifyPath(this.fileLocation + "/" + file.getName());
c.put(bis, uploadLocation);
} catch (SftpException e) {
throw new IllegalTargetException("Error occurred while uploading " + e.getMessage());
} finally {
try {
bis.close();
} catch (IOException e) {
throw new UnsupportedOperationException("Exception occurred while closing Input stream " + e.getMessage());
}
}
}
It would be grateful if you can show the conventional way of handling these situations.
原文:https://stackoverflow.com/questions/41245143
更新时间:2020-01-04 00:54
最满意答案
处理此问题的最佳方法是使用try-with-resource 。 但是,如果有人想要手动关闭连接并显示try或catch块的异常而不隐藏,则下面的代码片段就是解决方案。
public void upload(File file) throws IOException {
ChannelSftp c = (ChannelSftp) channel;
BufferedInputStream bis = new BufferedInputStream(file.toInputStream());
SftpException sftpException = null;
try {
String uploadLocation = Files.simplifyPath(this.fileLocation + "/" + file.getName());
c.put(bis, uploadLocation);
} catch (SftpException e) {
sftpException = e;
throw new IllegalTargetException("Error occurred while uploading " + e.getMessage());
} finally {
if (sftpException != null) {
try {
bis.close();
} catch (Throwable t) {
sftpException.addSuppressed(t);
}
} else {
bis.close();
}
}
}
Best way to handle this problem is to use try-with-resource. But if someone want to close the connection manually and show the exception of the try or catch block without hiding, following code snippet is the solution.
public void upload(File file) throws IOException {
ChannelSftp c = (ChannelSftp) channel;
BufferedInputStream bis = new BufferedInputStream(file.toInputStream());
SftpException sftpException = null;
try {
String uploadLocation = Files.simplifyPath(this.fileLocation + "/" + file.getName());
c.put(bis, uploadLocation);
} catch (SftpException e) {
sftpException = e;
throw new IllegalTargetException("Error occurred while uploading " + e.getMessage());
} finally {
if (sftpException != null) {
try {
bis.close();
} catch (Throwable t) {
sftpException.addSuppressed(t);
}
} else {
bis.close();
}
}
}
2016-12-20
相关问答
一般来说,不,这不是一个反模式。 finally块的重点在于确保事件被清除是否抛出异常。 异常处理的全部要点是,如果您无法处理,您可以通过相对干净的带外信令异常处理提供来让其冒泡。 如果您需要确保在抛出异常的情况下清除了这些东西,但是在当前范围内无法正确处理异常,则这是正确的。 你可能想要更加小心,确保你的最终块不会抛出。 In general, no, this is not an anti-pattern. The point of finally blocks is to make sure
...
我通常这样做: try {
// Use the resource.
} catch( Exception ex ) {
// Problem with the resource.
} finally {
// Put away the resource.
closeQuietly( resource );
}
别处: protected void closeQuietly( Resource resource ) {
try {
if (resource != nu
...
我认为问题在于即使使用AOP,也不能拦截异常消耗过程。 通过AOP,您可以捕获所创建的所有异常,但您无法知道它们何时被使用。 例如: try {
...
} catch (Exception e) {
log.boom("Ouchies happened here", e);
}
并不是每个例外都会被重新抛出。 但是,在某个级别上,最终会抛出MOST异常,以便调用者可以处理它们。 所以,鉴于你可能会“泄漏”例外,游戏将尝试找到“泄漏”的例外。 通过使用AOP,您可以在创建每个异常
...
执行此操作的最佳方法是将异常分配给可从块的其余部分访问的变量。 NSException *ex;
@try {
@try {
[someObject methodWhichCouldThrowException];
} @catch (NSException *e) {
ex = e;
} @finally {
[anotherObject methodWhichCouldThrowADifferentException];
...
只有在finally块中放入另一个try-catch块时。 否则它就像其他任何错误一样。 Only if you put another try-catch block in the finally block. Otherwise it's an error like any other.
处理此问题的最佳方法是使用try-with-resource 。 但是,如果有人想要手动关闭连接并显示try或catch块的异常而不隐藏,则下面的代码片段就是解决方案。 public void upload(File file) throws IOException {
ChannelSftp c = (ChannelSftp) channel;
BufferedInputStream bis = new BufferedInputStream(file.toInputStream
...
当在Finally块中引发一个excpetion时,没有什么特别的事情发生:异常会像任何其他异常一样向外传播,并且不会执行此finally块中的异常之后的代码。 如果strXMLfragment为null或空字符串(或由于已经运行的异步操作 ),您的第一次尝试将失败。 因此,如果您真的想要处理/吞下所有异常,则必须使用两个Try块。 In the end I came up with this profoundly simple and elegant refactoring: Try
wr
...
在Java 7及更高版本中,尝试使用处理可Closeable对象的资源。 重新格式化你的代码, try(JarFile jar = ....; URLClassLoader loader = ....;)
{
// work ...
}
只有实现了Closeable接口的类才能以这种方式工作,这两个类都符合这个标准。 In Java 7 and beyond, there is try with resources which handles Closeable objects. Re
...
如果您的代码无法完成其工作(也称为“履行合同”),则抛出异常。 这可能是因为调用者传递了无效输入,或者某些外部资源出现故障(例如网络连接丢失)。 当您可以以某种方式处理下游的预期问题时捕获异常。 例如,您可能会捕获指示网络问题的异常并重试操作几次,或者您可能会向用户显示错误消息并询问下一步该做什么。 如果下游代码可能抛出异常,但是您的代码位于中间某个位置并且不知道该怎么做,那么只需让异常移动到调用代码即可。 You throw an exception if your code can't do
...
这只是一个警告。 如果你阅读它的解释(重点是我的) 偶尔打算 ,这样的throw语句可能会掩盖抛出的异常,并极大地使调试复杂化。 如果你需要这样做,那就去做吧,但要确保它实际上是你想要做的,并且理解它的含义(类似于说“你真的想这么做吗?!”)。 并非所有IntelliJ的警告都可以消除。 根据后续进行编辑:您必须问自己,您的框架是否需要在finally块中抛出该异常。 你可以实现一个类似的方法来链接没有使用另一个函数的链接(只需用日志语句替换throw语句),但这可能不是理想的。 这完全取决于潜在
...