<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【106期】面試官:Java中的finally一定會(huì)被執(zhí)行嗎?

          共 4409字,需瀏覽 9分鐘

           ·

          2020-12-31 00:38

          程序員的成長(zhǎng)之路
          互聯(lián)網(wǎng)/程序員/技術(shù)/資料共享?
          關(guān)注


          閱讀本文大概需要 4 分鐘。

          來(lái)自:juejin.im/post/5ec2993fe51d45209d437387

          一、前言

          因?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:11
          復(fù)制代碼
          2.在執(zhí)行try塊之前制造一個(gè)錯(cuò)誤,直接爆紅

          public?class?TryCatchTest?{

          ??private?static?int?total()?{
          ????return?1?/?0;
          ????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());
          ??}
          }
          綜上我們看出,如果程序連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,就沒事了,都不執(zhí)行了。當(dāng)然這個(gè)情況是比較極端的,記住就行,沒事不要亂整這個(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塊中沒有返回值的話,就把之前保留的返回值返回出去。
          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值。
          推薦閱讀:
          【105期】面試官:注冊(cè)中心全部宕掉后,Dubbo服務(wù)還能進(jìn)行調(diào)用嗎?
          【103期】史上最全的數(shù)據(jù)庫(kù)面試題,面試前刷一刷!
          【102期】如何正確訪問(wèn)Redis中的海量數(shù)據(jù)?服務(wù)才不會(huì)掛掉!
          5T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機(jī),樹莓派,等等。在公眾號(hào)內(nèi)回復(fù)「2048」,即可免費(fèi)獲取??!

          微信掃描二維碼,關(guān)注我的公眾號(hào)

          朕已閱?

          瀏覽 80
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本高清三区 | 天天日天天操天天插 | 大粗鸡巴久久 | 大鸡巴在线播放 | 小早川怜子一区二区三区 |