Java 7中的 try-with-resource,在没有这个语法糖的情况下的等价实现是什么?
以下面的demo为例,这个问题目测99%的人都写不完全正确,不信来战。
public static void foo() throws Exception {
try (AutoCloseable c = dummy()) {
bar();
}
}
public static void bar() {
// may throw exception
}
我们凭第一感觉来写一下:
public static void foo() throws Exception {
AutoCloseable c = null;
try {
c = dummy();
bar();
} finally {
if (c != null) {
c.close();
}
}
}
看起来没什么问题,但是仔细想一下,如果bar()抛出了异常e1,c.close()也抛出了异常e2,调用者会收到哪个呢?
我们来回顾一下Java基础,try catch finally部分
public static void foo() {
try {
throw new RuntimeException("in try");
} finally {
throw new RuntimeException("in finally");
}
}
调用foo()函数最终会抛出什么异常呢?
运行一下:
Exception in thread "main" java.lang.RuntimeException: in finally
try中抛出的异常,就被finally中抛出的异常淹没掉了。
回到刚刚的问题,如果 bar() 和 c.close()同时抛了异常,那么调用端应该会收到c.close()抛出的异常e2, 往往这并不是我们想要的。那么怎么样抛出try中的异常,同时又不丢掉finally中的异常呢?
Java 7 中 为 Throwable 类 增 加 的 addSuppressed 方 法。当 一 个异 常 被 抛 出 的 时 候 , 可 能 有 其 他 异 常 因 为 该 异 常 而 被 抑 制 住 , 从 而 无 法 正 常 抛 出 。 这时 可 以 通 过addSuppressed 方 法 把 这 些 被 抑 制 的 方 法 记 录 下 来 。 被 抑 制 的 异 常 会 出 现在 抛 出 的 异 常 的 堆 栈 信 息 中 , 也 可 以 通 过 getSuppressed 方 法 来 获 取 这 些 异 常 。 这 样做 的 好 处 是 不 会 丢 失 任 何 异 常 , 方 便 开 发 人 员 进 行 调 试 。
有了上述概念,我们进行改写
```java
public static void foo() throws Exception {
AutoCloseable c = null;
Exception tmpException = null;
try {
c = dummy();
bar();
} catch (Exception e) {
tmpException = e;
throw e;
} finally {
if (c != null) {
if (tmpException != null) {
try {