[英]What is the gist of finally block in Java?
我想以下例子; 但無法弄清楚finally塊的重要性是什么。 你能告訴我這兩個代碼示例的執行區別嗎? 現實生活中的例子也很有幫助。
樣本1:
try{
// some code 1
}catch(Exception ex){
// print exception
}finally{
// some code 2
}
樣本2:
try{
// some code 1
}catch(Exception ex){
// print exception
}
// some code 2
你提出的兩個片段有很大的不同,例如當catch
塊本身拋出一個異常時, finally
塊仍然會被它的語義執行。
這是以下片段打印"Finally!"
,但不是"What about me???"
:
try {
throw null; // throws NullPointerException!
} catch (Exception e) {
int oops = 1/0; // throws ArithmeticException!
} finally {
System.out.println("Finally!"); // still gets executed!
}
System.out.println("What about me???"); // doesn't get executed!
一般來說, try
塊的finally
實際上總是被執行。 try
塊之后的任何代碼都沒有這樣的保證。
但是,如果我的
catch
塊只是一個簡單的
仍然無法保證它不會throw
東西。 在例如異常詳細消息的構造中,仍然可能出現問題。
即使您盡最大努力保證catch
代碼是“安全的”並且try
語句后面的代碼將始終執行,那么問題就變成“為什么?”。 為什么finally
要避免,然后再努力復制它的語義?
finally
語義是有保證的,不需要代碼的編寫者或讀者的證據負擔。 也正因為如此,它是地道的使用finally
阻止把強制“清理”代碼。 使用finally
保證正確性並增強可寫性和可讀性。
即使拋出了一個Error
,也會執行finally
塊,這不會被示例中的catch
塊catch
。 因此,您可以將清理代碼放在finally
塊中,該塊應始終運行,而不管try
和catch
塊中的操作結果如何。
請注意,通常catch
塊捕獲更多特定類型的異常 - 通常只檢查異常 - 因此在大多數情況下,上面兩個代碼示例之間的差異是非常明確的。
更新:您可能會說您的catch
塊永遠不會拋出異常,因此finally
不需要。 但請注意兩件事:
catch
塊中添加一些可能引發異常的代碼,會記得將清理后的代碼放到finally
塊? try-catch-finally
是一種編程習慣用法 ,它使人們更容易閱讀代碼來理解正在發生的事情。 如果你不使用常用的習語,就會產生誤解,從而導致長期的錯誤。 您使用finally
塊來清理並運行任何應該運行的代碼,無論是否拋出(和捕獲)異常。 這包括catch
塊中的代碼。
當我們想要釋放我們在try塊中使用的資源時,它會很有用。 因此,在任何情況下執行它們而不丟失的唯一地方是最終阻止。 因為如果拋出異常,java不會執行之后立即執行的代碼。 它直接跳轉到catch塊。
請注意,您甚至可以在沒有catch的情況下嘗試finally:
try{
// some code
}finally{
// cleanup code
}
因此,一個示例可能是一種想要將異常傳播給調用者的方法,但仍需要清理代碼,例如釋放外觀。
如果try塊中的語句拋出未經檢查的異常,則最終將執行塊以允許程序員采取相關操作。
在現實生活中,即使發生異常,finally塊也用於關閉打開的資源。 例如,當您讀取(或寫入)文件,訪問數據庫等時。
public void readFile(String fileName) {
FileReader fr;
BufferedFileReader bfr;
try {
fr = new FileReader(fileName);
bfr = new BufferedFileReader(fr);
// ...
} catch (IOException ioe) {
// ...
} finally {
// TO ENSURE THAT THE READERS ARE CLOSED IN ALL CASES
if (bfr != null) {
try {
bfr.close();
} catch (IOException ignoredIOE) {}
}
if (fr != null) {
try {
fr.close();
} catch (IOException ignoredIOE) {}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.