博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 7中的Try-with-resources
阅读量:5834 次
发布时间:2019-06-18

本文共 3215 字,大约阅读时间需要 10 分钟。

Try-with-resources是java7中一个新的异常处理机制,它能够很容易地关闭在try-catch语句块中使用的资源。

利用Try-Catch-Finally管理资源(旧的代码风格)

在java7以前,程序中使用的资源需要被明确地关闭,这个体验有点繁琐。

下面的方法读取文件,然后用System.out打印:

01 private static void printFile() throws IOException {
02     InputStream input = null;
03  
04     try {
05         input = <strong>new FileInputStream("file.txt")</strong>;
06  
07         int data = <strong>input.read()</strong>;
08         while(data != -1){
09             System.out.print((char) data);
10             data = <strong>input.read()</strong>;
11         }
12     finally {
13         if(input != null){
14             <strong>input.close()</strong>;
15         }
16     }
17 }

上面代码中黑体字的程序可能会抛出异常。正如你所看到的,try语句块中有3个地方能抛出异常,finally语句块中有一个地方会能出异常。

不论try语句块中是否有异常抛出,finally语句块始终会被执行。这意味着,不论try语句块中发生什么,InputStream 都会被关闭,或者说都会试图被关闭。如果关闭失败,InputStream’s close()方法也可能会抛出异常。

假设try语句块抛出一个异常,然后finally语句块被执行。同样假设finally语句块也抛出了一个异常。那么哪个异常会根据调用栈往外传播?

即使try语句块中抛出的异常与异常传播更相关,最终还是finally语句块中抛出的异常会根据调用栈向外传播。

在java7中,对于上面的例子可以用try-with-resource 结构这样写:

01 private static void printFileJava7() throws IOException {
02  
03     try(FileInputStream input = new FileInputStream("file.txt")) {
04  
05         int data = input.read();
06         while(data != -1){
07             System.out.print((char) data);
08             data = input.read();
09         }
10     }
11 }

注意方法中的第一行:

1 try(FileInputStream input = new FileInputStream("file.txt")) {

这就是try-with-resource 结构的用法。FileInputStream 类型变量就在try关键字后面的括号中声明。而且一个FileInputStream 类型被实例化并被赋给了这个变量。

当try语句块运行结束时,FileInputStream 会被自动关闭。这是因为FileInputStream 实现了java中的java.lang.AutoCloseable接口。所有实现了这个接口的类都可以在try-with-resources结构中使用。

当try-with-resources结构中抛出一个异常,同时FileInputStreami被关闭时(调用了其close方法)也抛出一个异常,try-with-resources结构中抛出的异常会向外传播,而FileInputStreami被关闭时抛出的异常被抑制了。这与文章开始处利用旧风格代码的例子(在finally语句块中关闭资源)相反。

使用多个资源

你可以在块中使用多个资源而且这些资源都能被自动地关闭。下面是例子:

01 private static void printFileJava7() throws IOException {
02  
03     try(  FileInputStream     input         = new FileInputStream("file.txt");
04           BufferedInputStream bufferedInput = new BufferedInputStream(input)
05     ) {
06  
07         int data = bufferedInput.read();
08         while(data != -1){
09             System.out.print((char) data);
10     data = bufferedInput.read();
11         }
12     }
13 }

上面的例子在try关键字后的括号里创建了两个资源——FileInputStream 和BufferedInputStream。当程序运行离开try语句块时,这两个资源都会被自动关闭。

这些资源将按照他们被创建顺序的逆序来关闭。首先BufferedInputStream 会被关闭,然后FileInputStream会被关闭。

自定义AutoClosable 实现

这个try-with-resources结构里不仅能够操作java内置的类。你也可以在自己的类中实现java.lang.AutoCloseable接口,然后在try-with-resources结构里使用这个类。

AutoClosable 接口仅仅有一个方法,接口定义如下:

1 public interface AutoClosable {
2  
3     public void close() throws Exception;
4 }

任何实现了这个接口的方法都可以在try-with-resources结构中使用。下面是一个简单的例子:

01 public class MyAutoClosable implements AutoCloseable {
02  
03     public void doIt() {
04         System.out.println("MyAutoClosable doing it!");
05     }
06  
07     @Override
08     public void close() throws Exception {
09         System.out.println("MyAutoClosable closed!");
10     }
11 }

doIt()是方法不是AutoClosable 接口中的一部分,之所以实现这个方法是因为我们想要这个类除了关闭方法外还能做点其他事。

下面是MyAutoClosable 在try-with-resources结构中使用的例子:

1 private static void myAutoClosable() throws Exception {
2  
3     try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
4         myAutoClosable.doIt();
5     }
6 }

当方法myAutoClosable.doIt()被调用时,下面是打印到System.out的输出:

1 MyAutoClosable doing it!
2 MyAutoClosable closed!

通过上面这些你可以看到,不论try-catch中使用的资源是自己创造的还是java内置的类型,try-with-resources都是一个能够确保资源能被正确地关闭的强大方法。

  • 转载自 
你可能感兴趣的文章
win7 64位+Oracle 11g 64位下使用 PL/SQL Developer 的解决办法
查看>>
BZOJ1997:[HNOI2010]PLANAR——题解
查看>>
HTML5新手入门指南
查看>>
opennebula 开发记录
查看>>
sql 内联,左联,右联,全联
查看>>
C++关于字符串的处理
查看>>
6、Web Service-拦截器
查看>>
Flask 源码流程,上下文管理
查看>>
Breaking parallel loops in .NET C# using the Stop method z
查看>>
修改故障转移群集心跳时间
查看>>
[轉]redis;mongodb;memcache三者的性能比較
查看>>
微软职位内部推荐-Sr DEV
查看>>
让你的WPF程序在Win7下呈现Win8风格主题
查看>>
802.11 学习笔记
查看>>
Leetcode-Database-176-Second Highest Salary-Easy(转)
查看>>
构建Docker Compose服务堆栈
查看>>
最小角回归 LARS算法包的用法以及模型参数的选择(R语言 )
查看>>
Hadoop生态圈-Kafka常用命令总结
查看>>
如何基于Redis Replication设计并实现Redis-replicator?
查看>>
浮点数内存如何存储的
查看>>