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 定义了三个相关的东西:

  1. AutoClosable
  2. try-with-resources
  3. 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

Author: [email protected]
Date: 2019-10-29 Tue 00:00
Last updated: 2022-02-26 Sat 00:02

知识共享许可协议