众所周知,所有被打开的系统资源,比如流、文件或者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===>");
        }
    }
}

results matching ""

    No results matching ""