天天看點

Java的finally了解

1.為什麼要用finally

先看一個沒有finally的異常處理try-catch語句:

如果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; //釋放資源

可是,假設在try或catch中有多條return語句,那麼在每條return語句之前,都要先運作釋放資源的語句:

public void f() throws Exception {

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

 try{

   doSomething;

   statementMayCauseException;  //可能會抛出異常的語句,若異常沒有被catch,則直接抛出,也不會運作到try-catch以下的語句

   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; //釋放資源

這樣,就須要在每個可能傳回的地方,以及每個可能出現異常而導緻程式跳轉的地方,考慮怎樣釋放資源,導緻複雜和備援。

是以,須要finally語句。

把資源釋放或狀态還原的代碼放到finally塊中,能夠保證在try和catch語句運作完後,一定會運作finally語句塊,而不用考慮各種複雜的跳轉情況。

int count = 0;

 count++;

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

}finally{

 count = 0;

2.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";   

  } 

 } 

 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.将暫時區域的傳回值送到上一級方法中。