🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
众所周知,所有被打开的系统资源,比如流、文件或者Socket连接等,都需要被开发者手动关闭,否则随着程序的不断运行,资源泄露将会累积成重大的生产事故。 在Java的江湖中,存在着一种名为finally的功夫,它可以保证当你习武走火入魔之时,还可以做一些自救的操作。在远古时代,处理资源关闭的代码通常写在finally块中。然而,如果你同时打开了多个资源,那么将会出现噩梦般的场景: ``` public class Demo { public static void main(String[] args) { BufferedInputStream bin = null; BufferedOutputStream bout = null; try { bin = new BufferedInputStream(new FileInputStream(new File("test.txt"))); bout = new BufferedOutputStream(new FileOutputStream(new File("out.txt"))); int b; while ((b = bin.read()) != -1) { bout.write(b); } } catch (IOException e) { e.printStackTrace(); } finally { if (bin != null) { try { bin.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (bout != null) { try { bout.close(); } catch (IOException e) { e.printStackTrace(); } } } } } } } ``` 我们用try-with-resource来改写刚才的例子: ``` public class TryWithResource { public static void main(String[] args) { try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new File("test.txt"))); BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(new File("out.txt")))) { int b; while ((b = bin.read()) != -1) { bout.write(b); } } catch (IOException e) { e.printStackTrace(); } } } ``` 示例: ``` public class AppTest { public static void main(String[] args){ try(Connection con = new Connection()) { con.print(); }catch (Exception e){ e.printStackTrace(); } } static class Connection implements AutoCloseable{ public void print(){ System.err.println("print data==>"); } @Override public void close() throws Exception { System.err.println("auto close===>"); } } } 语法糖原理: 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===>"); } } } ```