詳解Java中finally和return的執(zhí)行順序
Java中finally和return的執(zhí)行順序
try…catch…finally
try-catch-finally是一種針對程序運行時出錯的響應(yīng)手段,對于一些可以預(yù)料到的出錯類型,在發(fā)生時對其進行報告和補救。其使用流程如下:首先執(zhí)行try中的語句,如果try中的語句報錯了,那么就轉(zhuǎn)入對應(yīng)的catch語句中執(zhí)行處理異常的措施,catch后的語句中的內(nèi)容是對應(yīng)的錯誤類型。無論異常是否發(fā)生,finally中的內(nèi)容一定是會被執(zhí)行的,一般用來釋放資源,并確保某些操作一定會執(zhí)行。當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中是否還有返回語句,這里還有個小細節(jié)需要注意,finally里加上return過后,finally外面的return s就變成不可到達語句了,也就是永遠不能被執(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。



而實際運行代碼,我們得到的結(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. 當發(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)文件上傳下載和刪除功能
這篇文章主要為大家詳細介紹了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-04
Spring中實現(xiàn)策略模式的幾種方式小結(jié)
在寫業(yè)務(wù)代碼的時候,難免會遇到很多if-else,這個時候如果if-else不是很多可以用if-else,如果此時場景過多,太多的if-else會導致代碼比較臃腫,這個時候策略模式就出現(xiàn)了,本文主要闡述工作中常用的實現(xiàn)策略模式的幾種方式,需要的朋友可以參考下2024-05-05
SpringBoot整合新版SpringSecurity完整過程
Spring Security是保障Spring應(yīng)用程序安全的強大框架,而新版的Spring Security引入了lambda表達式來配置,使得安全配置更加簡潔、優(yōu)雅,本文將介紹如何在Spring Boot項目中整合新版Spring Security,需要的朋友可以參考下2024-02-02
java 使用memcached以及spring 配置memcached完整實例代碼
本篇文章主要介紹了java 使用memcached以及spring 配置memcached完整實例代碼,具有一定的參考價值,有興趣的可以了解一下2017-07-07

