簡體   English   中英

Java中finally塊的要點是什么?

[英]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塊只是一個簡單的print聲明呢?

仍然無法保證它不會throw東西。 在例如異常詳細消息的構造中,仍然可能出現問題。

即使您盡最大努力保證catch代碼是“安全的”並且try語句后面的代碼將始終執行,那么問題就變成“為什么?”。 為什么finally要避免,然后再努力復制它的語義?

finally語義是有保證的,不需要代碼的編寫者或讀者的證據負擔。 也正因為如此,它是地道的使用finally阻止把強制“清理”代碼。 使用finally保證正確性並增強可寫性和可讀性。

即使拋出了一個Error ,也會執行finally塊,這不會被示例中的catchcatch 因此,您可以將清理代碼放在finally塊中,該塊應始終運行,而不管trycatch塊中的操作結果如何。

請注意,通常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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM