前言
在 Java 中,不同情形下 return 和 finally 的執行順序很多人混淆不清。本文全面 & 詳細解析不同情形下return 和 finally的執行順序。
1. 儲備知識
- try / catch 是常見的捕捉異常 & 處理的語句
- 隻有 try 語句中抛出異常,才會執行 catch 中的語句
/**
* try中無抛出異常,則catch中的代碼不執行
*/
try{
// 代碼無抛出異常
return result;
}catch(Exception e){
// catch代碼
}
/**
* try中抛出異常,則執行catch中的語句
*/
try{
//代碼抛出異常
throw Exception;
return1 result1;
} catch(Exception e){
return2 result2; // 執行catch中的語句
}
無論什麼情況(異常與否、try / catch 前面存在return),finally塊代碼一定會執行
2. 場景分析
2.1 try 或 catch 中存在 return 語句、finally 無 return 語句
-
執行順序
return 後的語句-> finally 語句 -> return 結束函數 & 傳回值
- 栗子
/**
* 情況1:try中有return、無抛出異常
* 實際執行順序:
* 1. 執行 try塊語句
* 2. 執行 return後 的語句:得到結果result & 儲存下來
* 3. 執行 finally塊語句:不影響上述儲存的傳回值,哪怕修改了變量的值
* 4. 執行 return,結束函數,傳回result的值:依舊傳回步驟2儲存的結果
*/
try{
//代碼無抛出異常
return result;
}catch(Exception e){
}finally{
// finally代碼
}
/**
* 情況2:try中有return、抛出異常 、catch有return
* 實際執行順序:
* 1. 執行 try塊語句
* 2. 執行 throw 語句 :此時已抛出異常,運作因異常而終止,故不執行return1
* 3. 執行 catch塊語句
* 4. 執行 return2後 的語句:得到結果result2 & 儲存下來
* 5. 執行 finally塊語句:不影響上述儲存的傳回值,哪怕修改了變量的值
* 6. 執行 return2,結束函數,傳回result2的值:依舊傳回步驟4儲存的結果
*/
try{
//代碼抛出異常
throw Exception;
return1 result1;
}catch(Exception e){
return2 result2;
}finally{
// finally代碼
}
-
執行順序
當執行到finally語句的 return時,程式就直接傳回
- 栗子
/**
* 情況1:try & catch中都無return、無抛出異常 & finally中 有 return
* 實際執行順序:
* 1. 執行 try塊語句
* 2. 執行 finally塊語句:會影響傳回值
* 3. 執行 return,結束函數,傳回result的值
*/
try{
}catch(Exception e){
}finally{
return result ;
}
/**
* 情況2:try / catch中任意1者 或 都有return(try中的return和catch中的return最多隻有1個會執行)、finally中 有 return
* 實際執行順序:
* 1. 執行 try塊語句:設無抛出異常,則不執行catch語句 & return2
* 2. 執行 return1 後 的語句:得到結果result & 儲存下來
* 3. 執行 finally塊語句:不影響上述儲存的傳回值,哪怕修改了變量的值
* 4. 執行finally内的 return3 後語句:finally中的return會覆寫掉其它位置的return
* 5. 執行return3 ,結束函數,傳回result3的值
*/
try{
//throw Exception;
return1 result1;
}catch(){
return2 result2;
}finally{
return3 result3;
}
- 不要包含return語句,否則程式會提前退出
- 傳回值 ≠ try 或 catch中儲存的傳回值