<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>

          try catch finally的底層原理

          共 3143字,需瀏覽 7分鐘

           ·

          2021-11-19 17:35

          來源:https://blog.csdn.net/lwd512768098/article/details/114728720

          昨晚參加一個(gè)面試,被問到try catch finally相關(guān)的知識(shí),雖然之前了解過其中奇怪的用法,特別有return的情況,但是由于時(shí)間久遠(yuǎn),完全忘了,導(dǎo)致這個(gè)問題回答不是很好,只是知道finally無論是否發(fā)生異常都會(huì)執(zhí)行的(但是忘了含有return的情況是怎么處理的了),finally常常用來關(guān)閉一些資源,像文件,連接等。

          finally終究執(zhí)行

          我們先來驗(yàn)證一下finally終究執(zhí)行

          ????public?static?int?test()?{?
          ????????int?i?=?1;
          ????????try?{?
          ????????????i++;
          ????????}?finally?{?
          ????????????System.out.println("finally?yeah!");
          ????????}
          ????????return?i;
          ????}

          ????public?static?void?main(String[]?args)?{?
          ????????System.out.println(test());
          ????}

          輸出為


          ????public?static?int?test()?{?
          ????????int?i?=?1;
          ????????try?{?
          ????????????i++;
          ????????????throw?new?Exception();
          ????????}?catch?(Exception?e)?{?
          ????????????System.out.println("Exception?yeah!");
          ????????}?finally?{?
          ????????????System.out.println("finally?yeah!");
          ????????}
          ????????return?i;
          ????}

          ????public?static?void?main(String[]?args)?{?
          ????????System.out.println(test());
          ????}


          從上面兩個(gè)例子中我們可以看到,無論是正確運(yùn)行try塊還是在try塊發(fā)生了異常,finally塊都是被執(zhí)行的。搜索公眾號(hào)互聯(lián)網(wǎng)架構(gòu)回復(fù)“2T”,送你一份驚喜禮包。

          帶有return的情況

          finally不帶return的情況

          對(duì)于return情況的話,只要記住一句話就行,如果finally里面有return, 那么就會(huì)覆蓋try塊或者catch里面的return內(nèi)容,否則的話,在執(zhí)行finally的內(nèi)容之前(try塊或者catch里面有return語句),會(huì)計(jì)算好try或者catch里面的return表達(dá)式的值,然后保存到另一個(gè)局部變量,當(dāng)執(zhí)行fianlly的時(shí)候,會(huì)重新加載這個(gè)局部變量作為返回值,因此在finally的操作不會(huì)影響返回值,下面我們字節(jié)碼來看看內(nèi)部的工作原理。

          ????public?static?int?test()?{?
          ????????int?i?=?1;
          ????????try?{?
          ????????????i++;
          ????????????return?i;
          ????????}?finally?{?
          ????????????i++;
          ????????????System.out.println("finally?yeah!");
          ????????}
          ????}

          ????public?static?void?main(String[]?args)?{?
          ????????System.out.println(test());
          ????}

          第一個(gè)問題:在try塊中含有return語句,你覺得finally語句還有執(zhí)行么?
          第二個(gè)問題:最終結(jié)果是多少?

          從上面可以看到,盡管try塊里面有return, 但是finally塊仍然執(zhí)行了,你肯定會(huì)好奇,那為啥返回值是2呢,finally里面不是還進(jìn)行了i++么。搜索公眾號(hào)互聯(lián)網(wǎng)架構(gòu)師回復(fù)“2T”,送你一份驚喜禮包。
          簡單分析一下,從結(jié)果看,finally仍然執(zhí)行,說明try的return語句是還沒執(zhí)行的,下面我們看看字節(jié)碼。
          上面圖片已經(jīng)標(biāo)注很清楚了,如果還不明白的話,可以先去看一下這幾個(gè)字節(jié)碼命令,還是挺簡單的,注意的是,JVM操作都是基于操作數(shù)棧的。

          總結(jié)一下,總體的意思就是,當(dāng)執(zhí)行完try塊的時(shí)候,會(huì)計(jì)算return表達(dá)式的值,然后把這個(gè)返回值存在另一個(gè)臨時(shí)變量里面,最后返回的時(shí)候會(huì)重新讀取存放的變量,因此在finally后面無論如何修改,都不會(huì)影響返回值(除非finally里面含有return,這個(gè)我們?cè)谙旅嬗懻摚?/strong>

          finally帶有return

          上面的情況是try或者catch里面含有return,finally沒有return, 那么fianlly里面如何修改返回值是不會(huì)影響最后的返回值。下面討論finally里面含有return的情況。
          ????public?static?int?test()?{?
          ????????int?i?=?1;
          ????????try?{?
          ????????????i++;
          ????????????return?i;
          ????????}?finally?{?
          ????????????i++;
          ????????????System.out.println("finally?yeah!");
          ????????????return?i;
          ????????}
          ????}

          ????public?static?void?main(String[]?args)?{?
          ????????System.out.println(test());
          ????}

          相信各位能夠正常猜出結(jié)果了

          沒錯(cuò),返回了3,說明finally對(duì)i的修過是其效果的,我們從字節(jié)碼看看原因:

          從上圖可以看到,在返回之前,加載的是0槽位的變量,這時(shí)0槽位的變量的值是3,1槽位的變量是2,所以返回的3。
          由上可以得知,當(dāng)finally中含有return的時(shí)候,會(huì)覆蓋之前try或者catch(上面沒有貼出實(shí)驗(yàn),需要驗(yàn)證的可以去驗(yàn)證,作者本人是驗(yàn)證過了)里面的返回值的。搜索公眾號(hào)互聯(lián)網(wǎng)架構(gòu)回復(fù)“2T”,送你一份驚喜禮包。

          try, catch, finally均沒有return語句

          這種情況比較簡單,跟finally含有return類似

          ????public?static?int?test()?{?
          ????????int?i?=?1;
          ????????try?{?
          ????????????i++;
          ????????}?finally?{?
          ????????????i++;
          ????????????System.out.println("finally?yeah!");
          ????????}
          ????????return?i;
          ????}

          ????public?static?void?main(String[]?args)?{?
          ????????System.out.println(test());
          ????}


          總結(jié)

          這里總結(jié)一下,只要finally里面沒有return語句,那么返回值就由try或者catch的return語句決定,否則由finally的return語句決定


          PS:如果覺得我的分享不錯(cuò),歡迎大家隨手點(diǎn)贊、轉(zhuǎn)發(fā)、在看。


          瀏覽 48
          點(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>
                  成人精品在线观看 | 超碰在线操 | 久久精品毛片 | 国产精品久久久久久久曹县翰林府 | 日韩无码三级 |