try-with-resources 是Java7中增加的语法,相比于之前的try-catch-finally更简洁,更安全.
下面就让我们来看看他们之间的区别:
语法:
try-with-resources 支持自动按相反顺序关闭资源
try(多个资源){ 可能发生异常的业务代码; }
try-catch-finally
try{ 可能发生异常的业务代码; }catch(捕获的异常){ }fianlly{ 关闭资源 }
关闭io原来try-catch-finally:
1 static String readFirstLineFromFileWithFinallyBlock(String path) 2 throws IOException { 3 BufferedReader br = new BufferedReader(new FileReader(path)); 4 try { 5 return br.readLine(); 6 } finally { 7 if (br != null) br.close(); 8 } 9 }
其实这样在finally中还是可能会发生异常,所以方法还是要抛出异常(以防万一)
static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } }
再看一组对比:
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()); } } }
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代码块。在try-with-resources语句中,任何的catch和finally代码块都在所有被声明的资源被关闭后执行。
被压抑的异常
try-with-resources语句相关联的代码块可能会抛出异常。在writeToFileZipFileContents例子中,try代码块中可能会抛出异常,并且有高达两个异常可能会在try-with-resources语句抛出,当试图去关闭ZipFile和BufferedWriter对象的时候。如果在try代码块中抛出一个异常,同时在try-with-resources语句中抛出一个或多个异常,那么在try-with-resources语句中抛出的异常就被压抑了,并且最终在writeToFileZipFileContents方法抛出的异常就是try代码块中抛出的那个异常。你可以通过被try代码块抛出的异常的Throwable.getSuppressed方法找回被压抑的异常。
实现了AutoCloseable或Closeable接口的类
看
AutoCloseable
和
Closeable
接口的javadoc,看看实现了它们的类都有哪些。Closeable接口继承了AutoCloseable接口。不同之处在于,Closeable接口的close方法抛出的是IOException异常,AutoCloseable接口的close方法抛出的是Exception异常。 因此,AutoCloseable的子类可以重写close方法的行为,抛出指定的异常,比如IOException异常,甚至可以不抛出异常。