try catch finally的底層原理
AI全套:Python3+TensorFlow打造人臉識別智能小程序
最新人工智能資料-Google工程師親授 Tensorflow-入門到進階
黑馬頭條項目 - Java Springboot2.0(視頻、資料、代碼和講義)14天完整版
來源:https://blog.csdn.net/lwd512768098/article/details/114728720
昨晚參加一個面試,被問到try catch finally相關(guān)的知識,雖然之前了解過其中奇怪的用法,特別有return的情況,但是由于時間久遠,完全忘了,導(dǎo)致這個問題回答不是很好,只是知道finally無論是否發(fā)生異常都會執(zhí)行的(但是忘了含有return的情況是怎么處理的了),finally常常用來關(guā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());
????}
從上面兩個例子中我們可以看到,無論是正確運行try塊還是在try塊發(fā)生了異常,finally塊都是被執(zhí)行的。搜索公眾號互聯(lián)網(wǎng)架構(gòu)師回復(fù)“2T”,送你一份驚喜禮包。 帶有return的情況
finally不帶return的情況
對于return情況的話,只要記住一句話就行,如果finally里面有return, 那么就會覆蓋try塊或者catch里面的return內(nèi)容,否則的話,在執(zhí)行finally的內(nèi)容之前(try塊或者catch里面有return語句),會計算好try或者catch里面的return表達式的值,然后保存到另一個局部變量,當(dāng)執(zhí)行fianlly的時候,會重新加載這個局部變量作為返回值,因此在finally的操作不會影響返回值,下面我們字節(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());
????}第一個問題:在try塊中含有return語句,你覺得finally語句還有執(zhí)行么?
第二個問題:最終結(jié)果是多少?從上面可以看到,盡管try塊里面有return, 但是finally塊仍然執(zhí)行了,你肯定會好奇,那為啥返回值是2呢,finally里面不是還進行了i++么。搜索公眾號互聯(lián)網(wǎng)架構(gòu)師回復(fù)“2T”,送你一份驚喜禮包。 簡單分析一下,從結(jié)果看,finally仍然執(zhí)行,說明try的return語句是還沒執(zhí)行的,下面我們看看字節(jié)碼。 上面圖片已經(jīng)標(biāo)注很清楚了,如果還不明白的話,可以先去看一下這幾個字節(jié)碼命令,還是挺簡單的,注意的是,JVM操作都是基于操作數(shù)棧的。 finally帶有return
上面的情況是try或者catch里面含有return,finally沒有return, 那么fianlly里面如何修改返回值是不會影響最后的返回值。下面討論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());
????}沒錯,返回了3,說明finally對i的修過是其效果的,我們從字節(jié)碼看看原因:
從上圖可以看到,在返回之前,加載的是0槽位的變量,這時0槽位的變量的值是3,1槽位的變量是2,所以返回的3。 由上可以得知,當(dāng)finally中含有return的時候,會覆蓋之前try或者catch(上面沒有貼出實驗,需要驗證的可以去驗證,作者本人是驗證過了)里面的返回值的。搜索公眾號互聯(lián)網(wǎng)架構(gòu)師回復(fù)“2T”,送你一份驚喜禮包。 try, catch, 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語句決定
全棧架構(gòu)社區(qū)交流群
?「全棧架構(gòu)社區(qū)」建立了讀者架構(gòu)師交流群,大家可以添加小編微信進行加群。歡迎有想法、樂于分享的朋友們一起交流學(xué)習(xí)。
看完本文有收獲?請轉(zhuǎn)發(fā)分享給更多人
往期資源:
評論
圖片
表情







