1. 程式人生 > >try、catch、throw、throws、finally詳解

try、catch、throw、throws、finally詳解

一.關鍵字:throw,throws,try和catch的用法如下:

1、throws出現在方法的宣告中,表示該方法可能會丟擲的異常,允許throws後面跟著多個異常型別

2、throw出現在方法體中,用於丟擲異常。當方法在執行過程中遇到異常情況時,將異常資訊封裝為異常物件,然後throw,告知使用者。

3、try出現在方法體中,它自身是一個程式碼塊,表示嘗試執行程式碼塊的語句。如果在執行過程中有某條語句丟擲異常,那麼程式碼塊後面的語句將不被執行。

4、catch出現在try程式碼塊的後面,自身也是一個程式碼塊,用於捕獲異常try程式碼塊中可能丟擲的異常。catch關鍵字後面緊接著它能捕獲的異常型別,所有異常型別的子類異常也能被捕獲。

二.為什麼要使用 finally

1.假設 count 為需要使用的資源並且使用完之後需要釋放資源,那麼 我們可以吧釋放資源的語句放到 try-catch後執行,當前程式不管執不執行try-catch語句,都會執行釋放資源的語句

//初始化資源
int count = 0 ;

try{


count ++ ;

if(count==1)throw new Exception ("Exception in try");


}catch(Exception e){


System.out.println("catch block");

}

//釋放資源

count = 0;

2.但是當 try 或catch 中有多條 return 語句,那麼每次 return 之前,都需要執行釋放資源的語句

public void f() throws Exception {

int count = 0;  //初始化資源

try{

   doSomething;

   statementMayCauseException;  //可能會丟擲異常的語句,若異常沒有被catch,則直接丟擲,也不會執行到try-catch下面的語句

   doSomething;

   if(count == 1) throw new Exception1("E1 in try");

    if(count == 2) throw new Exception2("E2 in try");

}catch(Exception1 e){

   

count = 0; //釋放資源

    throw e;  //再次把異常丟擲,讓上一級捕獲。此時將不會執行catch外的語句,所以要先釋放資源



}catch(Exception2 e){



count = 0; //釋放資源

return; //返回了,也不會執行catch外的語句,所以要先釋放資源

}

count = 0; //釋放資源

}

3.這樣,就需要在每一個可能返回的地方,以及每一個可能出現異常而導致程式跳轉的地方,考慮如何釋放資源,導致複雜和冗餘。

所以,需要finally語句。

把資源釋放或狀態還原的程式碼放到finally塊中,可以保證在try和catch語句執行完後,一定會執行finally語句塊,而不用考慮各種複雜的跳轉情況。

int count = 0;

try{

count++;

if(count == 1)throw new Exception();

}catch(Exception e){

}finally{

count = 0;

}

4.finally什麼時候執行

finally在return語句之後,跳轉到上一級程式之前執行。

public class Test { 

public static void main(String[] args) {  

System.out .println(test ());  

}   

public static String test() {  

try {  

System.out .println("try block");  

return test1 ();  

} finally {  

System.out .println("finally block");

 //return "finally";   若開啟,則替換"after return" 

}  

}  

public static String test1() {  

System.out .println("return statement");  

 return "after return";  

}  

}

結果:

try block

return statement

finally block

after return

分析:

1.try語句塊,return test1(),則呼叫test1方法

2.test1()執行後返回"after return",返回值"after return"儲存在一個臨時區域裡

3.執行finally語句塊。若finally語句有返回值,則此返回值將替換掉臨時區域的返回值

4.將臨時區域的返回值送到上一級方法中。

如果若finally語句有返回值,則此返回值將替換掉臨時區域的返回值

5.驗證finally真正執行順序

package test;

import java.io.*;

public class Test1{

public static void main(String argv[]){

     Test1 m=new Test1();

     System.out.println(m.amethod());

 }

public int amethod(){

       try{

            FileInputStream dis =new FileInputStream("Hello.txt"); //1,丟擲異常

        }catch ( Exception ex) {

               System.out.println("No such file found");   //2.catch捕獲異常,並執行

               return -1;                                  //4,return 返回

        }finally{

               System.out.println("Doing finally");  //3.finally一定會執行,在return之前。(準確說,應該是return ;語句)

       }

         return 0;

    }

  }

    輸出結果為:

    No such file found

    Doing finally

    -1

總結:finally其實是僅在return ; 語句執行前執行,如果return 一個函式,那麼會先執行函式,但如果函式內有(return ;)語句,那麼finally就會在這個(return ;)語句前執行。

ps:如果catch塊有異常向外丟擲,執行順序呢:我執行說,你拋你得異常,我finally我的語句,我倆互不干涉,你別管我啥時執行,但我一定會執行。

關於finally,此時,應該很明朗了  您只需記著一點:除非呼叫system.exit()讓程式退出或斷電等因素致使程式中止,否則,無論任何因素,finally塊都一定會執行!!