ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
### 异常屏蔽 直接上代码: ``` public class Connection implements AutoCloseable { public void sendData() throws Exception { throw new Exception("send data"); } @Override public void close() throws Exception { throw new MyException("close"); } } public class TryWithResource { public static void main(String[] args) { try { test(); } catch (Exception e) { e.printStackTrace(); } } private static void test() throws Exception { Connection conn = null; try { conn = new Connection(); conn.sendData(); } finally { if (conn != null) { conn.close(); } } } } output==> basic.exception.MyException: close at basic.exception.Connection.close(Connection.java:10) at basic.exception.TryWithResource.test(TryWithResource.java:82) at basic.exception.TryWithResource.main(TryWithResource.java:7) ...... ``` 由于我们一次只能抛出一个异常,所以在最上层看到的是最后一个抛出的异常——也就是close方法抛出的MyException,而sendData抛出的Exception被忽略了。这就是所谓的异常屏蔽。由于异常信息的丢失,异常屏蔽可能会导致某些bug变得极其难以发现,程序员们不得不加班加点地找bug,如此毒瘤,怎能不除!幸好,为了解决这个问题,从Java 1.7开始,大佬们为Throwable类新增了addSuppressed方法,支持将一个异常附加到另一个异常身上,从而避免异常屏蔽。那么被屏蔽的异常信息会通过怎样的格式输出呢?我们再运行一遍刚才用try-with-resource包裹的main方法: ``` public class TryWithResource { public static void main(String[] args) { try (Connection conn = new Connection()) { conn.sendData(); } catch (Exception e) { e.printStackTrace(); } } } output==> java.lang.Exception: send data at basic.exception.Connection.sendData(Connection.java:5) at basic.exception.TryWithResource.main(TryWithResource.java:14) ...... Suppressed: basic.exception.MyException: close at basic.exception.Connection.close(Connection.java:10) at basic.exception.TryWithResource.main(TryWithResource.java:15) ... 5 more ``` 具体原因是编译器帮我们将一个异常附加到了另一个异常上\(var2.addSuppressed\(var11\)\): ``` public class AppTest { public AppTest() { } public static void main(String[] args) { try { AppTest.Connection con = new AppTest.Connection(); Throwable var2 = null; try { con.print(); } catch (Throwable var12) { var2 = var12; throw var12; } finally { if (con != null) { if (var2 != null) { try { con.close(); } catch (Throwable var11) { var2.addSuppressed(var11); } } else { con.close(); } } } } catch (Exception var14) { var14.printStackTrace(); } } static class Connection implements AutoCloseable { Connection() { } public void print() { System.err.println("print data==>"); } public void close() throws Exception { System.err.println("auto close===>"); } } } ```