try catch finally 執(zhí)行順序

在網(wǎng)上看到一些異常處理的面試題,試著總結(jié)一下矢空,先看下面代碼航罗,把這個(gè)方法在main中進(jìn)行調(diào)用打印返回結(jié)果,看看結(jié)果輸出什么屁药。

 public static  int testBasic(){
       int i = 1; 
       try{
           i++;
           System.out.println("try block, i = "+i);
       }catch(Exception e){
           i ++;
           System.out.println("catch block i = "+i);
       }finally{
           i = 10;
           System.out.println("finally block i = "+i);
       }
       return i;
}

沒錯(cuò)粥血,會(huì)按照順序執(zhí)行,先執(zhí)行try內(nèi)代碼段者祖,沒有異常的話進(jìn)入finally立莉,最后返回,那么輸出如下:

try block, i = 2
finally block i = 10
main test i = 10

這個(gè)沒有問題七问,如果我們把return語句放入try catch里又會(huì)怎么樣呢?

public static  int testBasic(){
       int i = 1; 
       try{
           i++;
           System.out.println("try block, i = "+i);
           return i;
       }catch(Exception e){
           i ++;
           System.out.println("catch block i = "+i);
           return i;
       }finally{
           i = 10;
           System.out.println("finally block i = "+i);
       }
}

輸出結(jié)果是:

try block, i = 2
finally block i = 10
main test i = 2

代碼順序執(zhí)行從try到finally蜓耻,由于finally是無論如何都會(huì)執(zhí)行的,所以try里的語句并不會(huì)直接返回械巡。在try語句的return塊中刹淌,return返回的引用變量并不是try語句外定義的引用變量i,而是系統(tǒng)重新定義了一個(gè)局部引用i’,這個(gè)引用指向了引用i對(duì)應(yīng)的值讥耗,也就是2有勾,即使在finally語句中把引用i指向了值10,因?yàn)閞eturn返回的引用已經(jīng)不是i,而是i',所以引用i的值和try語句中的返回值無關(guān)了古程。

但是蔼卡,這只是一部分,如果把i換成包裝類型而不是基本類型呢挣磨,來看看輸出結(jié)果怎樣雇逞,示例如下:

public static  List<Object> testWrap(){
       List<Object> list = new ArrayList<>();
       try{
           list.add("try");
           System.out.println("try block");
           return list;
       }catch(Exception e){
           list.add("catch");
           System.out.println("catch block");
           return list;
       }finally{
           list.add("finally");
           System.out.println("finally block ");
       }
}

打印結(jié)果如下:

try block
finally block
main test i = [try, finally]

可以看到荤懂,finally里對(duì)list集合的操作生效了,這是為什么呢塘砸。我們知道基本類型在棧中存儲(chǔ)节仿,而對(duì)于非基本類型是存儲(chǔ)在堆中的,返回的是堆中的地址掉蔬,因此內(nèi)容被改變了廊宪。

好了,現(xiàn)在我們?cè)趂inally里加一個(gè)return女轿,看看語句是從哪里返回的箭启。

public static  int testBasic(){
       int i = 1; 
       try{
           i++;
           System.out.println("try block, i = "+i);
           return i;
       }catch(Exception e){
           i ++;
           System.out.println("catch block i = "+i);
           return i;
       }finally{
           i = 10;
           System.out.println("finally block i = "+i);
           return i;
       }
}

輸出結(jié)果如下:

try block, i = 2
finally block i = 10
main test i = 10

可以看到,是從finally語句塊中返回的谈喳〔崃遥可見,JVM是忽略了try中的return語句婿禽。但I(xiàn)DE中會(huì)對(duì)finally中加的return有黃色警告提示赏僧,這是為什么呢,在try里加入一行會(huì)執(zhí)行異常的代碼扭倾,如下:

public static  int testBasic(){
       int i = 1; 
       try{
           i++;
           int m = i / 0 ;
           System.out.println("try block, i = "+i);
           return i;
       }catch(Exception e){
           i ++;
           System.out.println("catch block i = "+i);
           return i;
       }finally{
           i = 10;
           System.out.println("finally block i = "+i);
           return i;
       }
}

打印結(jié)果如下:

catch block i = 3
finally block i = 10
main test i = 10

可以看到淀零,因?yàn)閒inally中有return語句,try膛壹、catch中的異常被消化掉了驾中,屏蔽了異常的發(fā)生,這與初期使用try模聋、catch的初衷是相違背的肩民,因此編譯器也會(huì)提示警告。

那如果在finally中有異常發(fā)生链方,會(huì)對(duì)try持痰、catch中的異常有什么影響呢?

public static  int testBasic(){
       int i = 1; 
       try{
           i++;
           Integer.parseInt(null);
           System.out.println("try block, i = "+i);
           return i;
       }catch(Exception e){
           String.valueOf(null);
           System.out.println("catch block i = "+i);
           return i;
       }finally{
           i = 10;
           int m = i / 0;
           System.out.println("finally block i = "+i);
       }
}

這里我們?cè)趖ry祟蚀、catch里強(qiáng)行加上異常語句工窍,打印結(jié)果如下:

Exception in thread "main" java.lang.ArithmeticException: / by zero
at tryandcatch.TryAndCatch.testBasic(TryAndCatch.java:25)
at tryandcatch.TryAndCatch.main(TryAndCatch.java:45)

這個(gè)提示表示的是finally里的異常信息,也就是說一旦finally里發(fā)生異常前酿,try患雏、catch里的異常信息即被消化掉了,也達(dá)不到異常信息處理的目的罢维。

總結(jié)以上測(cè)試:

1淹仑、finally語句總會(huì)執(zhí)行

2、如果try、catch中有return語句匀借,finally中沒有return取试,那么在finally中修改除包裝類型和靜態(tài)變量、全局變量以外的數(shù)據(jù)都不會(huì)對(duì)try怀吻、catch中返回的變量有任何的影響(包裝類型、靜態(tài)變量會(huì)改變初婆、全局變量)

3蓬坡、盡量不要在finally中使用return語句,如果使用的話磅叛,會(huì)忽略try屑咳、catch中的返回語句,也會(huì)忽略try弊琴、catch中的異常兆龙,屏蔽了錯(cuò)誤的發(fā)生

4、finally中避免再次拋出異常敲董,一旦finally中發(fā)生異常紫皇,代碼執(zhí)行將會(huì)拋出finally中的異常信息,try腋寨、catch中的異常將被忽略

所以在實(shí)際項(xiàng)目中聪铺,finally常常是用來關(guān)閉流或者數(shù)據(jù)庫資源的,并不額外做其他操作萄窜。

注意String new 和 "" 是不一樣的铃剔。

1.String str1 = "abc";

String str2 = "abc";

sysout(str1==str2) 為 TRUE

解釋:棧中str1和str2都直接指向常量池中“abc”,==比較地址查刻,地址一樣键兜。

String str1 = "abc";

String str2 = new String(“abc”);

sysout(str1==str2)穗泵;為FALSE

解釋:str1指向常量池中“abc”普气,str2指向堆中新開辟的空間,所以地址不一樣火欧。

String str1 = "abc";

Stirng str2 = “ab”棋电;

str2=str2+“c”;

sysout(str1==str2)苇侵;為FALSE

解釋:str1指向常量池“abc”赶盔,str2指向堆中新開辟的空間,故地址不同榆浓。

String str1 = new String(“abc”)于未;

String str2 = new String(“abc”);

sysout(str1==str2);為FALSE

解釋:str1指向堆中開辟的空間烘浦,str2在堆中又重新開辟了空間抖坪,兩者并不是同一個(gè)空間,故地址不同闷叉。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末擦俐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子握侧,更是在濱河造成了極大的恐慌蚯瞧,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件品擎,死亡現(xiàn)場(chǎng)離奇詭異埋合,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)萄传,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門甚颂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秀菱,你說我怎么就攤上這事振诬。” “怎么了答朋?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵贷揽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我梦碗,道長(zhǎng)禽绪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任洪规,我火速辦了婚禮印屁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘斩例。我一直安慰自己雄人,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布念赶。 她就那樣靜靜地躺著础钠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叉谜。 梳的紋絲不亂的頭發(fā)上旗吁,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音停局,去河邊找鬼很钓。 笑死香府,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的码倦。 我是一名探鬼主播企孩,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼袁稽!你這毒婦竟也來了勿璃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤推汽,失蹤者是張志新(化名)和其女友劉穎蝗柔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體民泵,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年槽畔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了栈妆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡厢钧,死狀恐怖鳞尔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情早直,我是刑警寧澤寥假,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站霞扬,受9級(jí)特大地震影響糕韧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喻圃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一萤彩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧斧拍,春花似錦雀扶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至昂勉,卻和暖如春浪册,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背硼啤。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工议经, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斧账,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓煞肾,卻偏偏與公主長(zhǎng)得像咧织,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子籍救,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • https://www.ibm.com/developerworks/cn/java/j-lo-finally/ ...
    WY_250e閱讀 156評(píng)論 0 0
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法习绢,類相關(guān)的語法,內(nèi)部類的語法蝙昙,繼承相關(guān)的語法闪萄,異常的語法,線程的語...
    子非魚_t_閱讀 31,598評(píng)論 18 399
  • 當(dāng)汽車顛簸著啟動(dòng)的那一刻奇颠,坐在車上靠窗位置的我败去,看著小鎮(zhèn)偏南路口的街景一步步的倒退,營生的檔口烈拒、售賣汽車票的...
    鯨魚兒閱讀 451評(píng)論 0 1
  • 面對(duì)呼嘯而至的時(shí)代車輪圆裕,我們必須加速奔跑,有時(shí)會(huì)力不從心荆几,有時(shí)會(huì)浮躁焦慮吓妆,但必須適應(yīng),它可以輕易地將每一個(gè)落伍的個(gè)...
    曹冬賀閱讀 319評(píng)論 2 1