gpt4 book ai didi

Java - 检测 `finally` block 期间是否有异常发生

转载 作者:行者123 更新时间:2023-12-02 07:54:17 25 4
gpt4 key购买 nike

我正在根据 Java 语言规范考虑这一点:

If the catch block completes abruptly for reason R, then the finally block is executed. Then there is a choice:

  • If the finally block completes normally, then the try statement completes abruptly for reason R.

  • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

我有一个 block 如下:

try {
.. do stuff that might throw RuntimeException ...
} finally {
try {
.. finally block stuff that might throw RuntimeException ...
} catch {
// what to do here???
}
}

理想情况下,我希望在 finally block 中抛出的任何 RuntimeException 能够逃逸,仅当它不会导致 RuntimeException抛出在主 try block 中并被丢弃

Java中有什么方法可以让我知道与finally block 关联的 block 是否正常完成?

我猜我可以将一个 boolean 设置为主 try block 的最后一个语句(例如,completedNormally = true .这是最好的方法,还是有更好/更标准的方法?

最佳答案

我认为关键是不要失去最初的原因(如果有的话)。

如果我们看看 try-with-resources 的行为:

private static class SomeAutoCloseableThing implements AutoCloseable {

@Override
public void close() {
throw new IllegalStateException("closing failed");
}

}

public static void main(String[] args) {
try (SomeAutoCloseableThing thing = new SomeAutoCloseableThing()) {
throw new IllegalStateException("running failed");
}
}

我们最终得到:

Exception in thread "main" java.lang.IllegalStateException: running failed
at Main.main(Main.java:16)
Suppressed: java.lang.IllegalStateException: closing failed
at Main$SomeAutoCloseableThing.close(Main.java:9)
at Main.main(Main.java:17)

这个堆栈跟踪很棒,因为我们看到了两个异常,即我们不会丢失运行失败异常。

<小时/>

不使用 try-with-resources 来实现这一点,是错误的方式:

public static void main(String[] args) {
SomeAutoCloseableThing thing = new SomeAutoCloseableThing();
try {
throw new IllegalStateException("running failed");
} finally {
thing.close();
}
}

我们最终得到:

Exception in thread "main" java.lang.IllegalStateException: closing failed
at Main$SomeAutoCloseableThing.close(Main.java:9)
at Main.main(Main.java:19)

我们不知道运行失败也发生过,因为我们破坏了控制流,如果您需要调试这样的情况,那是非常糟糕的。

<小时/>

在不使用 try-with-resources 的情况下实现这一点,正确的方式(在我看来)是“记录并忘记”finally block 中发生的异常:

public static void main(String[] args) {
SomeAutoCloseableThing thing = new SomeAutoCloseableThing();
try {
throw new IllegalStateException("running failed");
} finally {
try {
thing.close();
} catch (Exception e) {
LoggerFactory.getLogger(Main.class).error("An error occurred while closing SomeAutoCloseableThing", e);
}
}
}

我们最终得到:

17:10:20.030 [main] ERROR Main - An error occurred while closing SomeAutoCloseableThing
java.lang.IllegalStateException: closing failed
at Main$SomeAutoCloseableThing.close(Main.java:10) ~[classes/:?]
at Main.main(Main.java:21) [classes/:?]
Exception in thread "main" java.lang.IllegalStateException: running failed
at Main.main(Main.java:18)

不如 try-with-resources 方法好,但至少我们知道实际发生了什么,没有丢失任何东西。

关于Java - 检测 `finally` block 期间是否有异常发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59360652/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com