Java中的快速失败finally子句

时间:2020-03-05 18:54:27  来源:igfitidea点击:

有没有一种方法可以从finally子句中检测到正在引发异常?

请参见下面的示例:

try {
    // code that may or may not throw an exception
} finally {
    SomeCleanupFunctionThatThrows();
    // if currently executing an exception, exit the program,
    // otherwise just let the exception thrown by the function
    // above propagate
}

还是唯一可以忽略的例外?

在C ++中,它甚至不允许我们忽略其中一种异常,而只是调用Terminate()。大多数其他语言使用与Java相同的规则。

解决方案

回答

不,我不相信。 catch块将在finally块之前运行完成。

try {
    // code that may or may not throw an exception
} catch {
// catch block must exist.
finally {
    SomeCleanupFunctionThatThrows();
// this portion is ran after catch block finishes
}

否则,我们可以添加一个异常代码将要使用的syncnize()对象,可以在finally块中签入,这将确定是否在单独的线程中正在运行异常。

回答

如果一个函数抛出并且想要捕获异常,则必须将该函数包装在try块中,这是最安全的方法。因此,在示例中:

try {
    // ...
} finally {
    try {
        SomeCleanupFunctionThatThrows();
    } catch(Throwable t) { //or catch whatever you want here
        // exception handling code, or just ignore it
    }
}

回答

设置一个标志变量,然后在finally子句中检查它,如下所示:

boolean exceptionThrown = true;
try {
   mightThrowAnException();
   exceptionThrown = false;
} finally {
   if (exceptionThrown) {
      // Whatever you want to do
   }
}

回答

我们是说要让try块根据try块是否成功完成而采取不同的行动吗?

如果是这样,我们可以随时执行以下操作:

boolean exceptionThrown = false;
try {
    // ...
} catch(Throwable t) {
    exceptionThrown = true;
    // ...
} finally {
    try {
        SomeCleanupFunctionThatThrows();
    } catch(Throwable t) { 
        if(exceptionThrown) ...
    }
}

但是,这令人费解。我们可能想考虑一种重组代码的方法,以使执行此操作变得不必要。

回答

如果我们发现自己这样做,则可能是设计有问题。 "最终"块的想法是,无论方法如何退出,我们都希望完成某些事情。在我看来,我们根本不需要finally块,而应该使用try-catch块:

try {
   doSomethingDangerous(); // can throw exception
   onSuccess();
} catch (Exception ex) {
   onFailure();
}