220812_《Effective Java》第9條:try-with-resources優先于try-finally
一、問題
Java類別庫中包含許多需要通過呼叫close來關閉的資源,例如:InputStream、Output Stream和java.sql.Connection,在編程程序中如果沒有關倍訓產生性能問題,
二、范例,使用try-finally
使用try-finally來關閉資源,如下所示:
public class FirstLineOfFile_Version1 {
static String firstLineOfFile(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
}
}
如果有兩個資源,我們會這樣來寫,但是不推薦這樣做,
public class Copy_Version1 {
final static int BUFFER_SIZE = 1024;
static void copy(String src, String dst) throws IOException {
InputStream in = new FileInputStream(src);
try {
OutputStream out = new FileOutputStream(dst);
try {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(buf)) > 0) {
out.write(buf, 0, n);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
這樣寫都能正確關閉資源,但是不推薦這樣寫,為什么呢?
因為在try塊和finally塊中都會拋出例外,在這種情況下第二個例外會完全抹除第一個例外,在例外堆疊軌跡中就看不到第一個例外的記錄,在現實系統中除錯會變得例外復雜,
三、范例,使用try-with-resources
Java 7引入了try-with-resources陳述句,解決了上述問題,要使用這個構造的資源,就必須實作AutoClosable介面,如果撰寫了一個類,如果它代表了是必須被關閉的資源,那么這個類也應該實作AutoClosable介面,下面來重寫firstLineFoFile以及copy方法:
public class FirstLineOfFile_Version2 {
static String firstLineOfFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
}
如果呼叫readLine和close方法拋例外,會拋出第一個例外,第二個例外會被禁止,這些禁止的例外不是被拋棄了也會列印在例外堆疊中,
public class Copy_Version2 {
final static int BUFFER_SIZE = 1024;
static void copy(String src, String dst) throws IOException {
try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst)
) {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(buf)) > 0) {
out.write(buf, 0, n);
}
}
}
}
try-with-resources還可以使用catch子句,這樣即可以處理例外,又不需要再套用一層代碼,
public class FirstLineOfFile_Version3 {
static String firstLineOfFile(String path, String defaultVal) {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch (IOException e) {
return defaultVal;
}
}
}
四、總結
在處理必須關閉的資源時,優先考慮try-with-resources,這樣寫的代碼簡潔、清晰,產生的例外也更有參考價值,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/501698.html
標籤:其他
上一篇:python包合集-cffi
