詳解Java中finally和return的執(zhí)行順序
Java中finally和return的執(zhí)行順序
try…catch…finally
try-catch-finally
是一種針對程序運(yùn)行時出錯的響應(yīng)手段,對于一些可以預(yù)料到的出錯類型,在發(fā)生時對其進(jìn)行報告和補(bǔ)救。其使用流程如下:首先執(zhí)行try
中的語句,如果try
中的語句報錯了,那么就轉(zhuǎn)入對應(yīng)的catch
語句中執(zhí)行處理異常的措施,catch
后的語句中的內(nèi)容是對應(yīng)的錯誤類型。無論異常是否發(fā)生,finally
中的內(nèi)容一定是會被執(zhí)行的,一般用來釋放資源,并確保某些操作一定會執(zhí)行。當(dāng)try和catch中有return時,finally中代碼仍然會執(zhí)行。
其使用的格式如下:
try { } catch (IOException e) { } finally { // 關(guān)閉資源 res.close(); }
1. finally語句在return語句執(zhí)行之后return返回之前執(zhí)行的
public class TestTryFinally { public static void main(String[] args) { System.out.println(test01()); } private static int test01() { int num = 0; try { System.out.println("try block"); num = 10; return num; } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); num = 30; } return num; } }
輸出結(jié)果:
try block
finally block
10
說明return
語句已經(jīng)執(zhí)行了再去執(zhí)行finally
語句,不過并沒有直接返回,而是等finally
語句執(zhí)行完了再返回結(jié)果。
public class TestTryFinally { public static void main(String[] args) { System.out.println(test02()); } private static String test02() { try { System.out.println("try block"); return test03(); } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); } return ""; } private static String test03() { System.out.println("invoke method: test03()"); return "method test03() return"; } }
輸出結(jié)果:
try block
invoke method: test03()
finally block
method test03() return
說明try
中的return
語句先執(zhí)行了但并沒有立即返回,等到finally
執(zhí)行結(jié)束后再返回。
2. finally塊中的return語句會覆蓋try塊中的return返回
public class TestTryFinally { public static void main(String[] args) { System.out.println(test04()); } /* * finally塊中的return語句會覆蓋try塊中的return返回 */ private static String test04() { String s = "init"; try { System.out.println("try block"); return "try"; } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); return "finally"; } // return s; } }
輸出結(jié)果:
try block
finally block
finally
這說明finally
里的return
直接返回了,就不管try
中是否還有返回語句,這里還有個小細(xì)節(jié)需要注意,finally
里加上return
過后,finally
外面的return s
就變成不可到達(dá)語句了,也就是永遠(yuǎn)不能被執(zhí)行到,所以需要注釋掉否則編譯器報錯。
3. 如果finally語句中沒有return語句覆蓋返回值,那么原來的返回值可能因為finally里的修改而改變也可能不變。
import java.util.*; public class TestTryFinally { public static void main(String[] args) { System.out.println(test01()); System.out.println("######################"); System.out.println(getMap().get("key").toString()); } private static int test01() { int num = 0; try { System.out.println("try block"); num = 10; return num; } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); num = 30; } return num; } public static Map<String, String> getMap() { Map<String, String> map = new HashMap<String, String>(); map.put("KEY", "INIT"); try { map.put("KEY", "TRY"); return map; } catch (Exception e) { map.put("KEY", "CATCH"); } finally { map.put("KEY", "FINALLY"); map = null; } return map; } }
我們先來看一下AI(ChatGPT3.5,Bard和文心一言3.5)給出的答案是什么。我們可以看到ChatGPT
和文心一言
給出的結(jié)果是:程序會拋出NullPointerException
異常,而Bard
給出的結(jié)果為:TRY
。
而實際運(yùn)行代碼,我們得到的結(jié)果為:FINALLY
。
輸出結(jié)果:
try block
finally block
10
######################
try block
finally block
finally
為什么test01()
中finally
里的num = 30;
并沒有起到作用,而getMap()
中finally
的map.put("key", "finally");
起了作用,而map = null;
卻沒起作用呢?這就是Java到底是傳值還是傳址的問題了,簡單來說就是:Java中只有傳值沒有傳址,這也是為什么map = null
這句不起作用。
4. try塊里的return語句在異常的情況下不會被執(zhí)行
public static void main(String[] args) { System.out.println(test06()); } private static int test05() { int num = 10; try { System.out.println("try block"); num = 5 / 0; return num; } catch (Exception e) { System.out.println("catch block"); num += 20; } finally { System.out.println("finally block"); num += 30; } return num; }
輸出結(jié)果:
try block
catch block
finally block
60
try
語句塊中發(fā)生了除0異常,所以try
中的return
不會被執(zhí)行到,而是接著執(zhí)行捕獲異常的catch
語句和最終的finally
語句,此時兩者對num
的修改都影響了最終的返回值。
5. 當(dāng)發(fā)生異常后,catch中的return執(zhí)行情況與未發(fā)生異常時try中return的執(zhí)行情況完全一樣
public static void main(String[] args) { System.out.println(test06()); } private static int test06() { int num = 10; try { System.out.println("try block"); num = 5 / 0; return num; } catch (Exception e) { System.out.println("catch block"); num += 20; return num; } finally { System.out.println("finally block"); num += 30; } // return num; }
輸出結(jié)果:
try block
catch block
finally block
30
說明了發(fā)生異常后,catch
中的return
語句先執(zhí)行,確定了返回值后再去執(zhí)行finally
塊,執(zhí)行完了catch
再返回,finally
里對num
的改變對返回值無影響,原因同前面一樣,也就是說情況與try
中的return
語句執(zhí)行完全一樣。
到此這篇關(guān)于Java中finally和return的執(zhí)行順序的文章就介紹到這了,更多相關(guān)Java finally和return 執(zhí)行順序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java利用apache ftp工具實現(xiàn)文件上傳下載和刪除功能
這篇文章主要為大家詳細(xì)介紹了Java利用apache ftp工具實現(xiàn)文件上傳下載、刪除功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-06-06關(guān)于Jsoup將相對路徑轉(zhuǎn)為絕對路徑的方法
這篇文章主要介紹了關(guān)于Jsoup將相對路徑轉(zhuǎn)為絕對路徑的方法,jsoup 是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文本內(nèi)容,需要的朋友可以參考下2023-04-04Spring中實現(xiàn)策略模式的幾種方式小結(jié)
在寫業(yè)務(wù)代碼的時候,難免會遇到很多if-else,這個時候如果if-else不是很多可以用if-else,如果此時場景過多,太多的if-else會導(dǎo)致代碼比較臃腫,這個時候策略模式就出現(xiàn)了,本文主要闡述工作中常用的實現(xiàn)策略模式的幾種方式,需要的朋友可以參考下2024-05-05java基礎(chǔ)之標(biāo)簽、按鈕和按鈕事件簡介
本文給大家?guī)淼氖莏ava圖形界面的基礎(chǔ)知識,簡單介紹了標(biāo)簽、按鈕和按鈕事件,十分的詳細(xì),有需要的小伙伴可以參考下。2015-06-06SpringBoot整合新版SpringSecurity完整過程
Spring Security是保障Spring應(yīng)用程序安全的強(qiáng)大框架,而新版的Spring Security引入了lambda表達(dá)式來配置,使得安全配置更加簡潔、優(yōu)雅,本文將介紹如何在Spring Boot項目中整合新版Spring Security,需要的朋友可以參考下2024-02-02java 使用memcached以及spring 配置memcached完整實例代碼
本篇文章主要介紹了java 使用memcached以及spring 配置memcached完整實例代碼,具有一定的參考價值,有興趣的可以了解一下2017-07-07