簡體   English   中英

try-finally 和 try-catch 的區別

[英]Difference between try-finally and try-catch

有什么區別

try {
    fooBar();
} finally {
    barFoo();
}

try {
  fooBar();
} catch(Throwable throwable) {
    barFoo(throwable); // Does something with throwable, logs it, or handles it.
}

我更喜歡第二個版本,因為它讓我可以訪問 Throwable。 這兩種變體之間是否有任何邏輯差異或首選約定?

另外,有沒有辦法從 finally 子句中訪問異常?

這是兩件不同的事情:

  • 只有在 try 塊中拋出異常時才會執行 catch 塊。
  • finally 塊總是在 try(-catch) 塊之后執行,無論是否拋出異常。

在您的示例中,您尚未顯示第三種可能的構造:

try {
    // try to execute this statements...
}
catch( SpecificException e ) {
    // if a specific exception was thrown, handle it here
}
// ... more catches for specific exceptions can come here
catch( Exception e ) {
    // if a more general exception was thrown, handle it here
}
finally {
    // here you can clean things up afterwards
}

而且,就像@codeca 在他的評論中所說的那樣,無法訪問 finally 塊內的異常,因為即使沒有異常,也會執行 finally 塊。

當然,您可以在塊外聲明一個保存異常的變量,並在 catch 塊內分配一個值。 之后,您可以在 finally 塊中訪問此變量。

Throwable throwable = null;
try {
    // do some stuff
}
catch( Throwable e ) {
    throwable = e;
}
finally {
    if( throwable != null ) {
        // handle it
    }
}

這些不是變化,它們是根本不同的東西。 finally始終執行,僅在發生異常時catch

finally 和 catch 塊是完全不同的:

  • 在 catch 塊中,您可以響應拋出的異常。 僅當存在未處理的異常並且類型與 catch 塊的參數中指定的異常或類型相匹配時,才會執行此塊。
  • 無論是否引發異常,最終都會在 try 和 catch 塊之后執行

所以

try {
  //some code
}
catch (ExceptionA) {
  // Only gets executed if ExceptionA 
  // was thrown in try block
}
catch (ExceptionB) {
  // Only executed if ExceptionB was thrown in try 
  // and not handled by first catch block
}

不同於

try {
  //some code
}
finally {
  // Gets executed whether or not 
  // an exception was thrown in try block
}

顯着地。

如果你定義了一個 try 塊,你必須定義

  1. 最后一個塊,或
  2. 一個或多個 catch 塊,或
  3. 一個或多個 catch 塊和一個 finally 塊

所以下面的代碼也是有效的:

try {
  //some code
}
catch (ExceptionA) {
  // Only gets executed if 
  // ExceptionA was thrown in try block
}
catch (ExceptionB) {
  // Only executed if ExceptionB was thrown in 
  // try and not handled by first catch block
}
//even more catch blocks
finally {
  // Gets executed whether or not an 
  // exception was thrown in try block
}

try用於運行可能拋出異常的方法

catch用於“捕獲”停止該異常

finally用於從捕獲或未捕獲異常中所需的任何清理

try{
    myObject.riskyMethod(); // run a method that may throw an exception
}
catch(Exception ex){
    myLogger.log(ex.Message); // "catch" stop that exception
}
finally{
    myObject = null; // clean up needed from that exception being caught
}
try {
    statements;
} catch (exceptionType1 e1) {      // one or multiple
    statements;                 
} catch (exceptionType2 e2) {
    statements;
}    
...
} finally {                                 // one or none
    statements;
}
  1. 所有 try 語句必須包含一個 catch 子句或一個 finally 子句
  2. 它可以有多個 catch 子句但只有一個 finally 子句
  3. 在任何執行過程中,如果發生任何錯誤,則 Control 將轉移到適當的 Catch 塊並執行語句並執行 finally 塊。

不管是什么,Finally 塊總是被執行,所以一般情況下,Finally 塊被使用,當你有會話、數據庫連接或文件或套接字打開時,就會放置關閉這些連接的代碼。 這只是為了確保在應用程序中沒有內存泄漏或不應發生任何其他問題。

finally 和 catch 塊是完全不同的:

在 catch 塊中,您可以響應拋出的異常。 僅當存在未處理的異常且類型與 catch 塊的參數中指定的異常或類型相匹配時,才會執行此塊。 無論是否引發異常,最終都會在 try 和 catch 塊之后執行。

在我的研究中,finally 塊總是被執行,它主要“用於關閉任何打開的連接”並銷毀不必要的東西。

通常,當我們使用流、連接等任何資源時,我們必須使用 finally 塊顯式關閉它們。 在下面給出的程序中,我們使用 FileReader 從文件中讀取數據,並使用 finally 塊關閉它。

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]){
      FileReader fr=null;       
      try{
         File file=new File("file.txt");
         fr = new FileReader(file);  char [] a = new char[50];
         fr.read(a); // reads the content to the array
         for(char c : a)
         System.out.print(c); //prints the characters one by one
      }catch(IOException e){
          e.printStackTrace();
       }
       finally{ 
          try{
              fr.close();
          }catch(IOException ex){       
               ex.printStackTrace();
           }
       }
    }

}

也許其他像我這樣的人搜索過這樣的東西。

來自此頁面的信息tutpoint

最后塊總是被執行。 只有在捕獲到與 blocks 參數匹配的異常時才會執行 catch block。

即使在第一種形式中,您也可以將其記錄在調用方法中。 所以除非你想在那里做一些特殊的處理,否則沒有什么大的優勢。

Try 塊將保存將引發異常的語句。 catch 塊將保存從 try 塊拋出的引用,並從 catch 塊生成所需的消息。 finally 塊還用於關閉使用的資源,如 io 關閉、文件關閉、dB 關閉。在 Java -9 中,增強的 try-with 資源出現在 try 之外聲明資源的地方。是強制性的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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