一、cffi cffi是連接Python與c的橋梁,可實現在Python中調用c文件。cffi為c語言的外部介面,在Python中使用該介面可以實現在Python中使用外部c文件的數據結構及函數。 二、直接在python中通過cffi定義c函數並使用 1、先通過pip3安裝cffi : pip3 i ...
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。這樣寫的代碼簡潔、清晰,產生的異常也更有參考價值。