检查finally中是否执行了try或执行了catch

Checking whether try was executed or catch was executed in finally

是否可以检查移交给 finally 的控制权是来自 try 还是 catch 之一? 类似于:

try {
    // Some code
} catch(Exception e) {
    // Some more code
} finally {
    // Check if control came from try or from catch?
}

Java 中没有自动执行此操作的方法。您可以创建一个布尔标志:

boolean isRaised = false;

try {
    // Some code
}
catch (Exception e) {
    isRaised = true;
}
finally {
    if (isRaised)
        System.out.println("from catch");
    else
        System.out.println("from try");
}

最好不要。

一般模式是:

try {
    someCodePossiblyRaisingAnException;
    preFinalOkayCode;
} catch (AbcException | DefException e) {
    preFinalFailedCode;
} finally {
    finalCode;
}

特别是使用 non-specific 异常被大多数 IDE 和代码检查器认为是糟糕的风格。

可能是使用异常的代码表明需要通用解决方案,并且重复了几次。在这种情况下,让调用者传播异常。例如 java swing 让按钮动作通过以下方式捕获异常:

protected ExceptionlessButton { // Or Action
    @Override
    public final void actionPerformed(ActionEvent evt) {
        try {
            onAction(e);
        } catch (Exception e) {
            ...
        }
    }
    abstract protected void onAction(ActionEvent evt);
}

在当前案例中,最终代码似乎属于 pre-final 代码部分之一。当考虑通常甚至可以消除 finally-blocks 的 try-with-resources 时,您可能会重新考虑这种概括的必要性。

Result f() throws SQLException {
    try (PreparedStatement stm = ...) {
        someCodePossiblyRaisingAnException;
        preFinalOkayCode;
        return result;
    }
}

作为替代方案怎么样:

try {
    // Some code
} catch(Exception e) {
    // Some more code
    //Code to execute for case where object thrown goes here.
    return; //Maybe return false or re-throw...
} finally{
    //Code to execute regardless of whether exception is thrown.
}
//Code to execute if no exception is thrown...
//return true;//?

如果 objective 要在 catch 案例之后继续,这可能需要在 (private) 函数中。

我之所以提出这个问题,是因为 finally 子句的想法是,无论是正常还是 exception-handling 控制流发生,它都是被执行的代码,问题是具体的寻找一种在这两种情况下执行不同代码的方法。所以似乎与目的背道而驰。

我们有一个模式!这是一个 catch 处理程序!

试图解决这个问题的代码是 'code smell'。 可能是因为 try 块太大,捕获了各种错误,应该是 sub-divided.

正如其他人指出的那样,您可以使用标志来指示已达到某些点,但这通常不是最佳方法。