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
***
友藏內心獨白:明日待續。
沒有留言:
張貼留言