您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Java中try-catch-finally執行順序是什么”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Java中try-catch-finally執行順序是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
這里共列舉五種情況,會對其一一說明。
try{ System.out.println("try塊代碼運行了"); return 0; }catch(Exception e){ System.out.println("catch塊代碼運行了"); }finally { System.out.println("finally塊代碼運行了"); } return 1;
輸出結果:
try塊代碼運行了
finally塊代碼運行了
最終返回:0
執行流程:
執行try塊中return前(包括return語句中的表達式運算)的代碼 -> 執行finally塊 -> 執行try中return。
結論:
當try中帶有return時,會先執行return前的代碼,然后暫時保存需要return的信息,再執行finally中的代碼,最后再通過return返回之前保存的信息。finally塊之后的語句return不再執行,因為程序在try中已經return過了,方法的執行已經結束。
但有一點需要注意,如果返回值是引用類型呢?再看另外一個例子:
List<Integer> list = new ArrayList<>(); try { list.add(0); System.out.println("try:" + list); return list; } catch (Exception e) { list.add(1); System.out.println("catch:" + list); } finally { list.add(2); System.out.println("finally:" + list); } return list;
輸出:
try:[0]
finally:[0,2]
最終返回:[0,2]
看完這個例子,可能會發現問題,剛提到return時會臨時保存需要返回的信息,不受finally塊中代碼的影響。但是在這里,list里存的不是變量本身,而是變量的地址,所以當finally通過地址改變了變量,還是會影響方法返回值的。
try{ System.out.println("try塊代碼運行了"); //int x = 1 / 0 ; }catch(Exception e){ System.out.println("catch塊代碼運行了"); return 0; }finally { System.out.println("finally塊代碼運行了"); } return 1;
輸出結果:
//無異常
try塊代碼運行了
finally塊代碼運行了
最終返回:1
//有異常
try塊代碼運行了
catch塊代碼運行了
finally塊代碼運行了
最終返回:0
執行流程:
程序先執行try,如果遇到異常執行catch塊。
有異常:執行catch中return之前(包括return語句中的表達式運算)代碼,再執行finally語句中全部代碼,最后執行catch塊中return, finally之后的return不再執行。
無異常:執行完try再finally再return。
結論:
catch中return與try中類似,若出現異常,會暫時保存catch塊中return的信息,再執行finally中的代碼,最后再通過return返回之前保存的信息。
try{ System.out.println("try塊代碼運行了"); return 0; }catch(Exception e){ System.out.println("catch塊代碼運行了"); }finally { System.out.println("finally塊代碼運行了"); return 1; }
輸出結果:
try塊代碼運行了
finally塊代碼運行了
最終返回:1
執行流程:
程序執行try塊中return之前(包括return語句中的表達式運算)代碼,再執行finally塊。因為finally塊中有return所以提前退出,而不再執行try中的return。
備注:
這種寫法是可以編譯通過的,但是編譯器會給予警告。我們一般不在finally塊中寫return語句,這里只是刻意演示了一下效果。
try{ System.out.println("try塊代碼運行了"); //int x = 1 / 0 ; }catch(Exception e){ System.out.println("catch塊代碼運行了"); return 0; }finally { System.out.println("finally塊代碼運行了"); return 1; }
輸出結果:
//無異常
try塊代碼運行了
finally塊代碼運行了
最終返回:1//有異常
try塊代碼運行了
catch塊代碼運行了
finally塊代碼運行了
最終返回:1
執行流程:
無異常:執行try后跳過catch執行finally,得到finally的返回值1;
有異常:程序執行catch塊中return之前(包括return語句中的表達式運算)代碼,再執行finally塊。因為finally塊中有return所以提前退出,而不再執行catch中的return。
try{ System.out.println("try塊代碼運行了"); //int x = 1 / 0 ; return 0; }catch(Exception e){ System.out.println("catch塊代碼運行了"); return 1; }finally { System.out.println("finally塊代碼運行了"); return 2; }
輸出結果:
//無異常
try塊代碼運行了
finally塊代碼運行了最終返回:2
//有異常
try塊代碼運行了
catch塊代碼運行了
finally塊代碼運行了最終返回:2
執行流程:
程序執行try塊中return之前(包括return語句中的表達式運算)代碼,
無異常:然后再執行finally塊,因為finally塊中有return所以提前退出;
有異常:執行catch塊中return之前(包括return語句中的表達式運算)代碼,再執行finally塊。因為finally塊中有return所以提前退出。
結論:
得到finally中的返回值3。
無論catch是否捕獲異常,finally語句塊都是要被執行的。
當try塊或catch塊return一個值,那么finally塊中的代碼會在執行return后,返回之前執行。(此時并沒有返回運算后的值,而是把要返回的值暫時保存起來)。
finally中如果包含return,那么程序將在這里返回,而不是通過try或catch中的return返回,返回值就不是try或catch中保存的返回值了。會直接在finally中結束方法的執行,導致try、catch中的return失效。
當try或catch,finally中都包含return的時候,要注意返回值的類型。finally修改的基本類型是不影響返回結果的,修改list、map、自定義類等引用類型時,是影響返回結果的。
編譯器會對finally中的return給予警告,因為從finally中返回可能會導致異常丟失 。如:
try { try { throw new RuntimeException("來自try塊中的異常") ; }finally{ return; } } catch (Exception e) { e.printStackTrace(System.out) ; }
這里無法捕獲 我們自定義的運行時異常。
又如:
try { try { throw new RuntimeException("來自try塊中的異常") ; }finally{ throw new RuntimeException("來自finally塊中的異常") ; } } catch (Exception e) { e.printStackTrace(System.out) ; }
這里會丟失 第一個異常。
讀到這里,這篇“Java中try-catch-finally執行順序是什么”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。