關(guān)于這個(gè)經(jīng)典問題,oracle其實(shí)有官方文檔來進(jìn)行闡釋。 Execution of try-finally and try-catch-finally
本文試圖對(duì)這部分文檔做一個(gè)簡(jiǎn)單的修改,制成偽碼形式,以加深記憶
java
// 翻譯版
執(zhí)行 try 塊;
if(try 塊的執(zhí)行順利完成){
執(zhí)行 finally 塊;
if(finally 塊正常執(zhí)行完成){
try 塊執(zhí)行正常完成; // 所以,即使try中有return語(yǔ)句,也會(huì)執(zhí)行finally的;
}else if(finally 塊由于原因 S 失敗,結(jié)束執(zhí)行){
try 塊執(zhí)行失敗,原因 S;
}
}else if (try 塊的執(zhí)行由于拋出異常 v 而終止){
if(如果 v 能夠與后續(xù)的 catch 語(yǔ)句異常類型匹配){
選擇第一個(gè)匹配的 catch 語(yǔ)句進(jìn)行 catch 語(yǔ)句執(zhí)行;
if(catch 塊正常執(zhí)行){
執(zhí)行 finally 塊;
if(finally 塊正常執(zhí)行){
try 塊正常結(jié)束執(zhí)行;
else if(finally 塊由于原因 S 異常終止){
try 塊由于原因 S 異常終止;
}
}else if(catch 塊由于原因 R 異常終止){
執(zhí)行 finally 塊;
if(finally 塊正常執(zhí)行){
try 語(yǔ)句由于原因 R 異常終止;
}else if(finally 塊由于原因 S 異常終止){
try 語(yǔ)句由于原因 S 異常終止(原因 R 被忽略);
}
}
}else{
執(zhí)行 finally 塊;
if(finally 塊正常執(zhí)行完成){
try 語(yǔ)句拋出異常 v;
}else if (finally 塊由于原因 S 異常終止){
try 語(yǔ)句由于原因 S 異常終止; ( 異常 v 將被無視)
}
}
}else if(try 語(yǔ)句由于其他原因 R 異常終止){
execute finally block;
if(finally 塊正常執(zhí)行){
try 語(yǔ)句由于 R 而異常終止;
}else if(finally 塊由于原因 S 異常終止){
try 語(yǔ)句由于原因 S異常終止(原因 R 忽略掉);
}
}
// 英語(yǔ)原文
execute try block;
if(execution of try block completes normally){
execute finally block;
if(finally block completes normally){
try block completes normally;
}else if(finally block completes abruptly for reason S){
try statement completes abruptly for reason S;
}
}else if (execution of try block completes abruptly because of a throw of a value v){
if(v is assignment compatible with a catchable exception class of any catch clause){
the first matchable catch clause is selected;
execute the selected catch clause with parameter v;
if(catch block completes normally){
execute the finally block;
if(finally block completes normally){
try block completes normally;
else if(finally block completes abruptly for reason S){
try statement completes abruptly for reason S;
}
}else if(catch block completes abruptly for reason R){
execute finally block;
if(finally block completes normally){
try statement completes abruptly for reason R;
}else if(finally block completes abruptly for reason S){
try statement completes abruptly for reason S(and reason R is discarded);
}
}
}else{
execute finally block;
if(finally block completes normally){
try statement complete abruptly because of a throw of v;
}else if (finally block completes abruptly for reason S){
try statement complete abruptly because of the reason S; ( the throw of v is discard and forgotten)
}
}
}else if(execution of try block completes abruptly because of any other reason R){
execute finally block;
if(finally block completes normally){
try statement completes abruptly for reason R;
}else if(finally block completes abruptly for reason S){
try statement completes abruptly for reason S(and reason R is discarded);
}
}