Java 7
中的 try-with-resource
,在没有这个语法糖的情况下的等价实现是什么?
以下面的demo为例,这个问题目测99%
的人都写不完全正确,不信来战。
public static void foo() throws Exception { |
我们凭第一感觉来写一下:
public static void foo() throws Exception { |
看起来没什么问题,但是仔细想一下,如果bar()
抛出了异常e1
,c.close()
也抛出了异常e2
,调用者会收到哪个呢?
我们来回顾一下Java基础,try catch finally
部分
public static void foo() { |
调用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
方 法 来 获 取 这 些 异 常 。 这 样做 的 好 处 是 不 会 丢 失 任 何 异 常 , 方 便 开 发 人 员 进 行 调 试 。
有了上述概念,我们进行改写
public static void foo() throws Exception { |
验证我们的想法 javap -c
查看字节码:
public static void foo() throws java.lang.Exception; |
从字节码逻辑,基本跟我们最后的逻辑一致。