Java 异常处理中对于 finally 的一些思考
一、前言
因?yàn)檫@次面試有問(wèn)到一些同學(xué)finally的問(wèn)題,發(fā)現(xiàn)自己這塊好像有點(diǎn)記不太清楚了,有的點(diǎn)可能還給人家說(shuō)錯(cuò)了,一度弄得場(chǎng)面有些尷尬。所以說(shuō)這篇文章深入研究一下finally的執(zhí)行情況和返回值的情況。
二、finally一定會(huì)執(zhí)行嗎?
先給答案:肯定不是。
我們可以看兩種情況:
1.在執(zhí)行try塊之前直接return,我們發(fā)現(xiàn)finally塊是不會(huì)執(zhí)行的
public?class?TryCatchTest?{private?static?int?total()?{int?i?=?11;if?(i?==?11)?{return?i;}try?{System.out.println("執(zhí)行try");}?finally?{System.out.println("執(zhí)行finally");}return?0;}public?static?void?main(String[]?args)?{System.out.println("執(zhí)行main:"?+?total());} } 輸出結(jié)果: 執(zhí)行main:112.在執(zhí)行try塊之前制造一個(gè)錯(cuò)誤,直接爆紅
public?class?TryCatchTest?{private?static?int?total()?{return?1?/?0;try?{System.out.println("執(zhí)行try");??//這行爆紅,原因就是無(wú)法訪問(wèn)}?finally?{System.out.println("執(zhí)行finally");}return?0;}public?static?void?main(String[]?args)?{System.out.println("執(zhí)行main:"?+?total());} }綜上我們看出,如果程序連try塊都執(zhí)行不到,那么finally塊自然就不會(huì)執(zhí)行到了。
不過(guò)這里有的同學(xué)就會(huì)問(wèn):如果執(zhí)行了try塊,finally塊一定會(huì)執(zhí)行嗎?有的同學(xué)答案就是一定會(huì),其實(shí)非然,看看下面的例子吧:
public?class?TryCatchTest?{private?static?int?total()?{try?{System.out.println("執(zhí)行try");System.exit(0);}?catch?(Exception?e)?{System.out.println("執(zhí)行catch");}?finally?{System.out.println("執(zhí)行finally");}return?0;}public?static?void?main(String[]?args)?{System.out.println("執(zhí)行main:"?+?total());} } 輸出結(jié)果: 執(zhí)行try我們?cè)趫?zhí)行try塊之中退出jvm,就沒(méi)事了,都不執(zhí)行了。當(dāng)然這個(gè)情況是比較極端的,記住就行,沒(méi)事不要亂整這個(gè)。最后總結(jié)一下:不管是給try塊中造了個(gè)異常,還是在try塊中進(jìn)行return,我們發(fā)現(xiàn)finally塊還是會(huì)執(zhí)行的。因?yàn)楫惓L幚碓O(shè)計(jì)初衷就是讓finally塊始終執(zhí)行。這個(gè)總結(jié)在finally的執(zhí)行時(shí)機(jī)得到證明。
三、finally執(zhí)行時(shí)機(jī)探討
首先看常規(guī)情況:
public?class?TryCatchTest?{private?static?int?total()?{try?{System.out.println("執(zhí)行try");return?11;}?finally?{System.out.println("執(zhí)行finally");}}public?static?void?main(String[]?args)?{System.out.println("執(zhí)行main:"?+?total());} } 輸出結(jié)果:執(zhí)行try執(zhí)行finally執(zhí)行main:11分析一下,不難得出在這個(gè)例子中finally塊執(zhí)行在try塊的return之前。我們給try塊中造一個(gè)異常:
public?class?TryCatchTest?{private?static?int?total()?{try?{System.out.println("執(zhí)行try");return?1?/?0;}?catch?(Exception?e)?{System.out.println("執(zhí)行catch");return?11;}?finally?{System.out.println("執(zhí)行finally");}}public?static?void?main(String[]?args)?{System.out.println("執(zhí)行main:"?+?total());} } 輸出結(jié)果:執(zhí)行try執(zhí)行catch執(zhí)行finally執(zhí)行main:11同樣的,finally執(zhí)行在catch塊return的執(zhí)行前。
四、finally塊中的返回值
1.finally塊不含返回值,但是做改變變量值的操作
看一個(gè)例子:
public?class?TryCatchTest?{private?static?int?total()?{int?i?=?0;try?{System.out.println("執(zhí)行try:"?+?i);return?i;}?finally?{++i;System.out.println("執(zhí)行finally:"?+?i);}}public?static?void?main(String[]?args)?{System.out.println("執(zhí)行main:"?+?total());} } 輸出結(jié)果: 執(zhí)行try:0 執(zhí)行finally:1 執(zhí)行main:0如果看完前面分析,會(huì)發(fā)現(xiàn)跟想象的不太一樣。我們經(jīng)過(guò)前面的分析,finally塊的執(zhí)行時(shí)機(jī)應(yīng)該是return之前,那理論上我們應(yīng)該先++i使得i等于1,在執(zhí)行return i;?自然會(huì)返回1。可是結(jié)果卻返回了0,這是因?yàn)镴ava程序會(huì)把try或者catch塊中的返回值保留,也就是暫時(shí)的確認(rèn)了返回值,然后再去執(zhí)行finally代碼塊中的語(yǔ)句。等到finally代碼塊執(zhí)行完畢后,如果finally塊中沒(méi)有返回值的話,就把之前保留的返回值返回出去。
2.finally中含有返回值
示例1:
public?class?TryCatchTest?{private?static?int?total()?{try?{System.out.println("執(zhí)行try");return?1;}?finally?{System.out.println("執(zhí)行finally");return?2;}}public?static?void?main(String[]?args)?{System.out.println("執(zhí)行main:"?+?total());} } 輸出結(jié)果: 執(zhí)行try 執(zhí)行finally 執(zhí)行main:2示例2:
public?class?TryCatchTest?{private?static?int?total()?{int?i?=?1;try?{System.out.println("執(zhí)行try:"?+?i);return?i;}?finally?{++i;System.out.println("執(zhí)行finally:"?+?i);return?i;}}public?static?void?main(String[]?args)?{System.out.println("執(zhí)行main:"?+?total());} } 輸出結(jié)果: 執(zhí)行try:1 執(zhí)行finally:2 執(zhí)行main:2示例3:
public?class?TryCatchTest?{private?static?int?total()?{int?i?=?1;try?{System.out.println("執(zhí)行try:"?+?i);}?finally?{++i;System.out.println("執(zhí)行finally:"?+?i);}return?i;}public?static?void?main(String[]?args)?{System.out.println("執(zhí)行main:"?+?total());} } 執(zhí)行結(jié)果: 執(zhí)行try:1 執(zhí)行finally:2 執(zhí)行main:2這三個(gè)示例都說(shuō)明了一點(diǎn),在分析含有finally塊的方法返回值時(shí),要對(duì)于return出現(xiàn)的地方進(jìn)行具體分析。在finally塊中進(jìn)行return操作的話,則方法整體的返回值就是finally塊中的return返回值。如果在finally塊之后的方法內(nèi)return,則return的值就是進(jìn)行完上面的操作后的return值。
總結(jié)
以上是生活随笔為你收集整理的Java 异常处理中对于 finally 的一些思考的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Netty实现自定义协议
- 下一篇: 选择一线一张床还是小城一套房?