看下面一段例子
static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
这是java SE7之前我们处理一些需要关闭的资源的做法,无论是否出现异常都要对资源进行关闭。
这时如果try块和finally块中的方法都抛出异常那么try块中的异常会被抑制(suppress),只会抛出finally中的异常,而把try块的异常完全忽略。
这里如果我们用catch语句去获得try块的异常,也没有什么影响,catch块虽然能获取到try块的异常但是对函数运行结束抛出的异常并没有什么影响。readFirstLineFromFileWithFinallyBlock执行结束抛出的便是finally块的异常。如下:
static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} catch (IOException e) {
System.out.println("这里是try块的异常");
} finally {
if (br != null) br.close();
}
}
try-with-resources语句
try-with-resources语句能够帮你自动调用资源的close()函数关闭资源不用到finally块。
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
这是try-with-resources语句的结构,在try关键字后面的( )里new一些需要自动关闭的资源。
这个时候如果方法 readLine 和自动关闭资源的过程都抛出异常,那么:
- 函数执行结束之后抛出的是try块的异常,而try-with-resources语句关闭过程中的异常会被抑制,放在try块抛出的异常的一个数组里。(上面的非try-with-resources例子抛出的是finally的异常,而且try块的异常也不会放在fianlly抛出的异常的抑制数组里)
- 可以通过异常的public final synchronized Throwable[] getSuppressed() 方法获得一个被抑制异常的数组。
- try块抛出的异常调用getSuppressed()方法获得一个被它抑制的异常的数组,其中就有关闭资源的过程产生的异常。
try-with-resources语句能放多个资源
try (ZipFile zf = new ZipFile(zipFileName);
BufferedWriter writer = newBufferedWriter(outputFilePath, charset)
) {
//执行任务
}
最后任务执行完毕或者出现异常中断之后是根据new的反向顺序调用各资源的close()的。例如这里先关闭writer再关闭zf。
try-with-resources语句也可以有catch和finally块。
这两个块必须是在try-with-resources语句所声明的资源关闭之后才会运行。
try (Statement stmt = con.createStatement()) {
//xx程序
} catch (SQLException e) {
JDBCTutorialUtilities.printSQLException(e);
} finally {
//oo程序
}
}
– –>执行xx程序后并关闭stmt 资源,如果xx程序抛出异常被catch到执行JDBCTutorialUtilities.printSQLException(e);,最后执行oo程序。
那些资源需要关闭呢?
官方的说法是:
The try-with-resources statement is a try statement that declares one or more resources. A resource is as an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
1、try-with-resources语句是一个声明了一个或者多个资源的语句。
2、资源就是一个在程序运行结束之后需要close的对象。
3、每个实现了AutoCloseable(或者Closeable)的对象都是资源。