如何保持finally块的抛出异常?

时间:2013-03-20 13:19:18

标签: java exception idioms control-flow

我有以下代码:

try {
    /* etc. 1 */
} catch (SomeException e) {
    /* etc. 2 */
} catch (SomeException e) {
    /* etc. 3 */
} finally {
    /* 
     * do something which depends on whether any exception was caught,
     * but should only happen if any exception was caught.
     */

    /* 
     * do something which depends on whether an exception was caught and
     * which one it was, but it's essentially the same code for when no
     * exception was caught.
     */
}

所以,我想保留我的异常。除了在每个catch块中分配变量之外,还有什么方法可以做到这一点吗?

编辑:为了澄清,请不要发布答案,建议我在try块外部使用变量作用域。我知道我能做到这一点,这个问题的重点是寻找替代方案。

现在,我真正喜欢拥有的是更灵活的catch块,因此多个catch块可以捕获相同的异常,例如catch(Exception e)即使已被抓住,也会抓住所有内容,catch(Exception e) except(NullPointerException, IllegalArgumentException)会跳过除外。并且catch块可以catchingcontinue;跳过同一个try块的所有其他catch块,catchingbreak;跳过finally。

4 个答案:

答案 0 :(得分:2)

试试这个:

try {
    // your code throwing exceptions
} catch (Exception e) { // This catch any generic Exception
    // do whatever you want to do with generic exception
    ...
    if (e instanceof SomeException) {
        ...
    } else if (e instanceof OtherException) {
        ...
    }
}

使用java 7甚至可以这样做:

try {
    // your code throwing exceptions
} catch (SomeException|OtherException e) { // This catch both SomeException and OtherException
    // do whatever you want to do with generic exception
    ...
    if (e instanceof SomeException) {
        ...
    } else if (e instanceof OtherException) {
        ...
    }
}

答案 1 :(得分:1)

您需要将其分配到variable块之外的try-catch,并在finally块上使用它。

Exception caughtException = null;

try {
    /* etc. 1 */
} catch (SomeException e) {
    caughtException= e;
} catch (SomeOtherException e) {
    caughtException= e;
} finally {
    if (caughtException != null) {
        /* 
         * do something which depends on whether any exception was caught,
         * but should only happen if any exception was caught.
         */
    }
}

看起来你想做一些审核。为什么不使用一些注释和AOP来处理行为,当然还有一个很好的异常处理来捕获之前或之后的异常。

答案 2 :(得分:1)

将变量保留在catch块的范围之外,并将其分配给catch块。

购买我强烈建议您不要这样做。

最后块应该用于资源清理或任何需要运行的类似功能,无论例外情况如何。

所有异常处理都应该在catch块中完成,而不是finally块。

答案 3 :(得分:1)

我在这里建议您将异常处理的详细信息提取到新方法中,并从catch块中调用这些方法,这些方法尽可能具体,以避免instanceof检查。这样做的好处是不使用instanceof,在catch块而不是finally中保留异常处理代码,并清楚地将共享异常处理代码与特定异常处理代码分开。是的,在三个catch块之间有一些共享代码,但它只是一行清晰的代码,这对我来说似乎是可以接受的。

try {
    // do work that uses resources and can generate any of several exceptions
} catch (SomeException1 e) {
    standardExceptionHandler(e);
    specificExceptionHandler1(e);
} catch (SomeException2 e) {
    standardExceptionHandler(e);
    specificExceptionHandler2(e);
} catch (Exception e) {
    standardExceptionHandler(e);
} finally {
    // this would include only code that is needed to cleanup resources, which is
    // what finally is supposed to do.
}