這節講的是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