在Java中,是否有一种优雅的方法来检测在运行finally块之前是否发生了异常?在处理"close()"语句时,通常需要在finally块中进行异常处理。理想情况下,我们希望保留两个异常并将它们传播上去(因为它们都可能包含有用的信息)。我能想到的唯一方法是在try-catch-finally范围外部有一个变量来保存抛出的异常的引用。然后,将“保存”的异常与finally块中发生的任何异常一起传播上去。
有没有更加优雅的方法?也许有API调用可以揭示这一点?
以下是大致的代码示例:
显然,还有其他类似的折衷方案,可能涉及将异常保存为成员变量,从方法返回异常等等...但我正在寻找更加优雅的解决方案。也许像Thread.getPendingException()这样的东西或类似的东西?就此而言,其他语言中是否有优雅的解决方案呢?
这个问题实际上是由另一个问题中的评论引发的,该评论提出了一个有趣的问题。
有没有更加优雅的方法?也许有API调用可以揭示这一点?
以下是大致的代码示例:
Throwable t = null;
try {
stream.write(buffer);
} catch(IOException e) {
t = e; //Need to save this exception for finally
throw e;
} finally {
try {
stream.close(); //may throw exception
} catch(IOException e) {
//Is there something better than saving the exception from the exception block?
if(t!=null) {
//propagate the read exception as the "cause"--not great, but you see what I mean.
throw new IOException("Could not close in finally block: " + e.getMessage(),t);
} else {
throw e; //just pass it up
}
}//end close
}
显然,还有其他类似的折衷方案,可能涉及将异常保存为成员变量,从方法返回异常等等...但我正在寻找更加优雅的解决方案。也许像Thread.getPendingException()这样的东西或类似的东西?就此而言,其他语言中是否有优雅的解决方案呢?
这个问题实际上是由另一个问题中的评论引发的,该评论提出了一个有趣的问题。
IDisposableEx
接口,其中包括一个IDisposable(Exception ex)
方法,并且当可用时,编译器的using
块将使用该接口。在许多情况下,如果使用using
块来封装锁的代码引发异常,则正确的操作不应释放锁,也不应无限期地保留它,而是应将其 作废,以便任何待处理或未来尝试获取锁的尝试都将立即抛出异常。 - supercat