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