Try With Resources
Table of Contents
1. Try With Resources
1.1. try finally
在 java 7 之前, 都会使用 try-finally 保证资源被释放:
System.out.println("-----------------------"); MyResource r = null; try { r = new MyResource(); throw new RuntimeException("running error"); } finally { if (r != null) { r.close(); } }
但有一个问题: 若 r.close() 时抛出了异常 A, 则整个函数会抛出 A, 而忽略了 `running error` 这个异常.
1.2. try with resources
为了解决上面的问题, java 7 定义了三个相关的东西:
- AutoClosable
- try-with-resources
- supressed exception
class MyResource implements AutoCloseable { @Override public void close() { System.out.println("MyResource closed"); throw new RuntimeException("close error"); } } public class Test { static void testTry() { System.out.println("-----------------------"); MyResource r = null; try { r = new MyResource(); throw new RuntimeException("running error"); } finally { if (r != null) { r.close(); } } } static void testTryWithResource() { System.out.println("-----------------------"); try (MyResource r = new MyResource()) { throw new RuntimeException("running error"); } } static void testSurpressedException() { System.out.println("-----------------------"); RuntimeException e = new RuntimeException("running error"); e.addSuppressed(new RuntimeException("supressed 1")); e.addSuppressed(new RuntimeException("supressed 2")); e.addSuppressed(new RuntimeException("supressed 3")); throw e; } public static void main(String argv[]) { try { testTry(); } catch (Exception e) { e.printStackTrace(System.out); } try { testTryWithResource(); } catch (Exception e) { e.printStackTrace(System.out); } try { testSurpressedException(); } catch (Exception e) { e.printStackTrace(System.out); } } }
MyResource closed java.lang.RuntimeException: close error at MyResource.close(Test.java:5) at Test.testTry(Test.java:18) at Test.main(Test.java:41)
MyResource closed java.lang.RuntimeException: running error at Test.testTryWithResource(Test.java:26) at Test.main(Test.java:47) Suppressed: java.lang.RuntimeException: close error at MyResource.close(Test.java:5) at Test.testTryWithResource(Test.java:27) … 1 more
java.lang.RuntimeException: running error at Test.testSurpressedException(Test.java:32) at Test.main(Test.java:53) Suppressed: java.lang.RuntimeException: supressed 1 at Test.testSurpressedException(Test.java:33) … 1 more Suppressed: java.lang.RuntimeException: supressed 2 at Test.testSurpressedException(Test.java:34) … 1 more Suppressed: java.lang.RuntimeException: supressed 3 at Test.testSurpressedException(Test.java:35) … 1 more