11

Java的try、catch、finally(1):Java SE 7之前

 2 years ago
source link: https://teddy-chen-tw.blogspot.com/2013/11/javatrycatchfinally1java-se-7.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

2013年11月12日 星期二

Java的try、catch、finally(1):Java SE 7之前

Nov. 06 16:22~17:47

Java SE 7之前

寫了這麼多篇Java例外處理的文章,只談過checked與unchecked exception的差別,還沒有正式介紹過Java的例外處理機制。鄉民們可能會想:「Java的例外處理不就是try、catch、finally這三個關鍵字就搞定了嗎,有什麼好講的?」如上圖所示,在Java SE 7之前,Java的例外處理的主要框架的確是依靠try、catch、finally來達成。鄉民們可以使用try、catch,try、finally、或是try、catch、finally這三種不同的方式來捕捉與處理例外。這三者的用途分別是:

  • try:如果想要在method裡面捕捉例外,必須要可能發生例外的程式碼放到try block裡面,否則例外只能往外傳遞。
  • catch:catch block一定會跟在try block後面,如果想捕捉try block所發生的例外,就把這個例外的型態寫在catch子句裡面,例如catch(IOException e)就可以捕捉到IOException這種型態的例外。如果想要捕捉多種例外型態,就必須要撰寫多個catch block,例如:
   1: public void try_multiple_catch(){
   2:     try{
   3:         throwIOException();
   4:         throwSQLException();
   5:     }
   6:     catch(IOException e){
   7:     }
   8:     catch(SQLException e){
   9:     }
  10:     catch(Exception e){
  11:       // blanket catch
  12:     }
  13: }
上面程式範例的try block呼叫throwIOException()與throwSQLException()這兩個method,他們分別會丟出IOException與SQLException。為了捕捉這兩個例外,需要寫兩個catch block(6~9行)。最後catch(Exception e)的這個catch block有一個術語,叫做blanket catch,用來捕抓除了Error型態以外的全部例外。這種寫法是因為有時候鄉民們不希望自己的method丟出例外,因此用一個blanket catch把所有例外都捕捉起來。由於Error例外在Java語言中代表嚴重的錯誤,通常是由JVM所發出,例如OutOfMemoryError,而且一旦發生大部分的情況會導致程式終止。因此blanket catch通常只捕捉Exception而非Throwable。但如果鄉民們在某種特殊情況下想要連Error都一起捕捉,則可以用catch(Throwable e)的方式來實作blanket catch。

Java的例外類別繼承架構,捕捉Exception會捕捉除了Error以外的全部例外。

當多個catch block同時出現的時候,這些catch block出現的順序就很重要。如下圖程式片段所示,如果把catch(Exception e)寫在其他catch block前面,那麼所有的例外都會被第一個catch(Exception e)給捕捉到,後面那兩個catch block(9~12行)也就沒有機會被執行到。

   1: public void incorrect_try_multiple_catch(){
   2:     try{
   3:         throwIOException();
   4:         throwSQLException();
   5:     }
   6:     catch(Exception e){
   7:           // blanket catch
   8:     }
   9:     catch(IOException e){
  10:     }
  11:     catch(SQLException e){
  12:     }
  13: }
  • finally:最後這個finally block是用來釋放在try block裡面所使用的資源。不管在try block是否發生例外,只要寫了finally block,程式的執行順序最後一定會跑到這裡面。就算是直接在try或是catch裡面使用return指令,finally block也還是會被執行。請看下列程式範例:
   1: public static int try_finally_with_return() {
   2:         try {
   3:             System.out.println("execute try block");
   4:             return 1;
   5:         }
   6:         finally{
   7:             System.out.println("execute finally block");
   8:             return 0;
   9:         }
  10: }
  11:  
  12: public static void main( String[] args )
  13: {
  14:     System.out.println("call try_finally_with_return : " 
  15:                             + try_finally_with_return());
  16: }
鄉民們猜一下main()程式呼叫try_finally_with_return()之後會傳回1還是0?答案是傳回0,因為finally block一定會被執行。
execute try block
execute finally block
call try_finally_with_return : 0

世事無絕對,當然也有例外。當JVM執行到try block或是catch block裡面的程式碼,但是JVM自己本身卻被終止執行時,finally block便不會被執行到。請參考以下範例:

   1: public static void main( String[] args )
   2: {
   3:     try {
   4:         System.out.println("execute try block");
   5:         System.exit(0);
   6:     } 
   7:     finally{
   8:         System.out.println("execute finally block");
   9:     }
  10: }
因為在try block裡面直接呼叫System.exit(0),終止整個程式的執行,所以finally block並不會被執行到。執行結果如下列所示:
   execute try block

友藏內心獨白:明日待續。

沒有留言:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK