Java 7开始,提供了一种新的语法try-with-resources
用于在资源使用完毕后自动关闭资源,和python中的with
语句类似。“资源”指的是实现了java.lang.AutoCloseable
的任意对象,因为java.io.Closeable
是AutoCloseable
的子接口,所以实现了Closeable
的对象也可以用于该语法。
从文件中读取第一行,无论try{}
中的代码块是正常结束还是抛出异常(BufferdReader .readLine throw IOException
),BufferdReader
都会在使用完后会被自动关闭
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
Java 7之前,可以使用finally来实现类似的效果
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
但是finally
方式和try-with-resources
方式还是有所区别。finally
方式中,如果readLine()
和close()
都同时抛出异常,try{}
代码块中readLine()
抛出的异常被捕获,抑制抛出,而finally{}
代码块中的close()
抛出的异常被向上层调用抛出。try-with-resources
对异常抑制的处理和finally
相反,如果异常同时在try{}
代码块和try-with-resources
语句中抛出,最后try{}
代码块中的异常将被抛出,try-with-resources
语句中的异常会被抑制,如果需要获得被抑制的异常,可以通过对抛出的异常调用Throwable.getSuppressed()
提取。
从zip文件中读取其中的文件名,然后写入一个文本文件中,通过分号分隔,try-with-resources
语句中可以声明多个资源
public static void writeToFileZipFileContents(String zipFileName,
String outputFileName)
throws java.io.IOException {
java.nio.charset.Charset charset =
java.nio.charset.StandardCharsets.US_ASCII;
java.nio.file.Path outputFilePath =
java.nio.file.Paths.get(outputFileName);
// Open zip file and create output file with
// try-with-resources statement
try (
java.util.zip.ZipFile zf =
new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer =
java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
// Enumerate each entry
for (java.util.Enumeration entries =
zf.entries(); entries.hasMoreElements();) {
// Get the entry name and write it to the output file
String newLine = System.getProperty("line.separator");
String zipEntryName =
((java.util.zip.ZipEntry)entries.nextElement()).getName() +
newLine;
writer.write(zipEntryName, 0, zipEntryName.length());
}
}
}
声明多个资源时,资源关闭的顺序与try-with-resources
语句中声明的正好相反,上面的例子中,BufferedWriter
先关闭,然后ZipFile
才关闭。
利用try-with-resources
语句自动的关闭java.sql.Statement
。
public static void viewTable(Connection con) throws SQLException {
String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";
try (Statement stmt = con.createStatement()) {
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String coffeeName = rs.getString("COF_NAME");
int supplierID = rs.getInt("SUP_ID");
float price = rs.getFloat("PRICE");
int sales = rs.getInt("SALES");
int total = rs.getInt("TOTAL");
System.out.println(coffeeName + ", " + supplierID + ", " +
price + ", " + sales + ", " + total);
}
} catch (SQLException e) {
JDBCTutorialUtilities.printSQLException(e);
}
}
try-with-resources可以像传统的try语句一样,拥有配套的catch和finally语句块,需要注意的是任何catch和finally语句块都在声明的资源被关闭之后才被运行。