这节讲的是Java7中引入的使用try语句进行资源管理的新用法。这节的内容与上一节介绍的异常处理的关系比较密切。上节中介绍的Throwable中的新方法addSuppressed就是为try-with-resourcces语句添加的。对于资源管理,大多数开发人员都知道的一条原则是:谁申请,谁释放。这些资源涉及操做系统中的主存、磁盘文件、网络链接和数据库链接等。凡是数量有限的、须要申请和释放的实体,都应该归入到资源管理的范围中来。java
在使用资源的时候,有可能会抛出各类异常,好比读取磁盘文件和访问数据库时均可能出如今各类不一样的异常。而资源管理的一个要求就是无论操做是否成功,所申请的资源都要被正确释放。上一节中咱们有比较典型的资源释放的示例,这里咱们要讲一讲java7中对资源管理的加强。Java7中对try语句进行了加强,使它能够支持对资源进行管理,保证资源老是被正确释放。如例:sql
package test; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class ResourceBasicUsage { public String readFile(String path) throws IOException { try(BufferedReader reader = new BufferedReader(new FileReader(path))) { //注意这里 StringBuilder builder = new StringBuilder(); String line = null; while((line = reader.readLine()) != null){ builder.append(line); builder.append(String.format("%n")); } return builder.toString(); } } public static void main(String[] args) { ResourceBasicUsage usage = new ResourceBasicUsage(); try { System.out.println(usage.readFile("F:/manifest_provider_loophole.txt")); } catch (IOException e) { e.printStackTrace(); } } }
上面的代码并不须要使用finally语句来保证打开的流被正确关闭,这是自动完成的。相对于传统的使用finally语句的作法,这种方式简单得多。开发人员只须要关心使用资源的业务逻辑便可。资源的申请是在try子句中进行的,而资源的释放是自动完成的。在使用try-with-resources语句的时候,异常可能发生在try语句中,也可能发生在释放资源时。若是资源初始化时或try语句中出现异常,而释放资源的操做正常执行,try语句中的异常会被抛出。若是try语句和释放资源都出现了异常,那么最终抛出的异常是try语句中出现的异常,在释放资源时出现的异常会做为被抑制的异常添加进去,即经过Throwable.addSuppressed方法来实现。数据库
可以被try语句所管理的资源须要知足一个条件,那就是其java类要实现java.lang.AutoCloseable接口,不然会出如今编译错误。当须要释放资源的时候,该接口的close方法会被自动调用。Java类库中已有很多接口或类继承或实现了这个接口,使得它们能够用在try语句中。在这些已有的常见接口或类中,最经常使用的就是与I/O操做和数据库相关的接口。与I/O相关的java.io.Closeable继承了AutoCloseable,而与数据库相关的java.sql.Connection、java.sqlResultSet和java.sql.Statement也继承了该接口。若是但愿本身开发的类也能利用try语句的自动化资源管理,只须要实现AutoCloseable接口便可。网络
除了对单个资源进行管理以外,try-with-resources还能够对多个资源进行管理。如例:app
package test; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class MultipleResourcesUsage { public void copyFile(String fromPath,String toPath) throws IOException { try(InputStream input = new FileInputStream(fromPath); //注意,这里用了分号 OutputStream output = new FileOutputStream(toPath)){ byte[] buffer = new byte[8192]; int len = -1; while((len = input.read(buffer)) != -1){ output.write(buffer, 0, len); } } } public static void main(String[] args) { MultipleResourcesUsage usage = new MultipleResourcesUsage(); try { usage.copyFile("F:/manifest_provider_loophole.txt", "F:/aaa.txt"); } catch (IOException e) { e.printStackTrace(); } } }
当对多个资源进行管理的时候,在释放每一个资源时均可能会产生异常。全部这些异常都会被加到资源初始化异常或try语句块中抛出的异常的被抑制异常列表中。ide
在try-with-resource语句中也可使用catch和finally子句。在catch子句中能够捕获try语句块和释放资源时可能发生的各类异常。
oop