在Java中,try-with-resources的关键任务是自动和正确地释放资源。在Java 7出现之前,程序员必须在finally块中手动关闭资源。这导致了代码重复和频繁的错误。
在Java 6及之前,资源(开放文件、流、连接)必须通过finally手动管理,这经常导致内存泄漏。
手动编写的资源关闭代码是错误的来源,尤其是在处理多个异常和复杂的catch块层次结构时。没有保证在发生错误时会调用close()。
自Java 7起,引入了try-with-resources语法,它保证为每个实现了AutoCloseable接口的资源自动调用close()方法。
代码示例:
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) { String line = reader.readLine(); System.out.println(line); } catch (IOException e) { e.printStackTrace(); } // reader会自动关闭
关键特点:
AutoCloseable接口的对象才能在try-with-resources中使用。问题1:资源需要实现哪个接口才能用于try-with-resources?
AutoCloseable。任何实现此接口(或Closeable)的对象都可以在该结构中使用。
问题2:如果在try-with-resources中有多个资源,关闭的顺序是什么?
资源按其声明的反向顺序关闭(后进先出):
try (A a = new A(); B b = new B()) { ... } // b.close()会第一个被调用,然后是a.close()
问题3:可以对非标准对象使用try-with-resources吗,例如没有实现AutoCloseable的网络连接?
不可以,但可以在自己的类中手动实现AutoCloseable。之后该对象将与try-with-resources兼容。
开发人员通过finally手动关闭JDBC连接和Statement。当第二个异常发生时,Statement的关闭未执行,连接“挂起”并隐藏了错误。
优点:
缺点:
在文件加载模块中引入try-with-resources后,所有流会自动关闭,代码变得更短,文件描述符泄漏的bug消失了。
优点:
缺点: