亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中return和finally的執行順序是什么

發布時間:2022-05-23 14:55:07 來源:億速云 閱讀:161 作者:iii 欄目:大數據

這篇文章主要介紹“Java中return和finally的執行順序是什么”,在日常操作中,相信很多人在Java中return和finally的執行順序是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java中return和finally的執行順序是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

源碼:

public class ReturnFinallyDemo {     public static void main(String[] args) {         System.out.println(case1());     }      public static int case1() {         int x;         try {             x = 1;             return x;         } finally {             x = 3;         }     } }  # 輸出

上述代碼的輸出可以簡單地得出結論:return在finally之前執行,我們來看下字節碼層面上發生了什么事情。下面截取case1方法的部分字節碼,并且對照源碼,將每個指令的含義注釋在后面:

iconst_1 // 將常量1推入操作數棧頂  istore_0 // 彈出棧頂元素(1),保存到局部變量表slot[0],此時slot[0]=1。這兩條指令對應源碼:x = 1;  iload_0 // 將局部變量表slot[0]的值推入操作數棧頂,也就是說把上面x的值推入棧頂  istore_1 // 彈出棧頂元素(1),保存到局部變量表slot[1],此時slot[1]=1。其實,此時就已經把要return的值準備好了  iconst_3 // 將常量3推入操作數棧頂,這一條指令開始,其實是開始執行finally中的代碼了  istore_0 // 彈出棧頂元素(3),保存到局部變量表slot[0],此時slot[0]=3。這兩個指令對應源碼:x = 3;這里要注意的是,雖然都是更新了x的值,但是finally中的x和try中x的賦值,保存在了不同的局部變量表中 iload_1 // 將局部變量表slot[1]的值推入操作數棧頂,此時棧頂元素的值為1,是第3行指令保存的值  ireturn // 將操作數棧頂的值返回給調用方

從字節碼來看,似乎又是finally的代碼先執行了,因為ireturn指令確實是在最后執行的,所以返回什么樣的值不在于誰先執行,而在于ireturn指令返回的操作數棧頂的元素是何時保存的。在上述代碼環境中,是try代碼塊中給x賦值的版本,也就是緊接著return語句后面的x所保存的版本。

下面再來看一個稍微復雜點的場景:

public static int case2() {     int x;     try {         x = 1;         return ++x;     } finally {         x = 3;     } }  # 輸出

有了上面的分析,這個就很好理解了,我們還是來看下字節碼:

iconst_1 // 將常量1推入操作數棧頂 istore_0 // 彈出棧頂元素(1),保存到局部變量表slot[0],此時slot[0]=1。這兩條指令對應源碼:x = 1; iinc          0, 1 // 對局部變量表slot[0]進行自增(+1)操作,此時slot[0]=2,對應源碼:++x;所以,可以看出return后面的表達式先執行 iload_0 // 將局部變量表slot[0]的值推入操作數棧頂,也就是說把上面x的值(2)推入棧頂 istore_1 // 彈出棧頂元素(2),保存到局部變量表slot[1],此時slot[1]=2。其實,此時就已經把要return的值準備好了 iconst_3 // 將常量3推入操作數棧頂,這一條指令開始,其實是開始執行finally中的代碼了 istore_0 // 彈出棧頂元素(3),保存到局部變量表slot[0],此時slot[0]=3。這兩個指令對應源碼:x = 3;這里要注意的是,雖然都是更新了x的值,但是finally中的x和try中x的賦值,保存在了不同的局部變量表中 iload_1 // 將局部變量表slot[1]的值推入操作數棧頂,此時棧頂元素的值為2,是第6行指令保存的值,也就是經過++x之后的值 ireturn // 將操作數棧頂的值返回給調用方

從上述代碼可以看出,return后面的指令先執行,然后保存到局部變量表,接著執行finally中的語句,最后執行return指令本身。

總結一下,return指令是最后執行的,如果return后面有表達式,則執行完表達式之后就執行finally中的語句,最后再執行return指令。所以說finally和return到底哪個先執行:return指令后面如果有表達式或方法調用的話,先執行,然后執行finally,最后執行return指令。就像上面的程序演示的結果,不能光從x的賦值來看最終返回結果,從指令層面看,兩次對x的賦值,保存在局部變量表的位置不一樣。

最后,再來看一個平時不會這么去寫的場景:

public static int case3() {     int x;     try {         x = 1;         return ++x;     } finally {         x = 3;         return x;     } } # 輸出

這是一個finally返回結果的示例,平時不建議這么寫,我們同樣從字節碼的角度來分析下:

iconst_1 // 將常量1推入操作數棧頂 istore_0 // 彈出棧頂元素(1),保存到局部變量表slot[0],此時slot[0]=1。這兩條指令對應源碼:x = 1; iinc          0, 1 // 對局部變量表slot[0]進行自增(+1)操作,此時slot[0]=2,對應源碼:++x;所以,可以看出return后面的表達式先執行 iload_0  // 將局部變量表slot[0]的值推入操作數棧頂,也就是說把上面x的值(2)推入棧頂 istore_1 // 彈出棧頂元素(2),保存到局部變量表slot[1],此時slot[1]=2。 iconst_3 // 將常量3推入操作數棧頂,這一條指令開始,其實是開始執行finally中的代碼了 istore_0 // 彈出棧頂元素(3),保存到變量表slot[0],此時slot[0]=3。這兩個指令對應源碼:x = 3 iload_0  // 將局部變量表slot[0]的值(3)推入操作數棧,這是跟之前不一樣的地方,ireturn返回的值選擇的局部變量表不一樣 ireturn

到此,關于“Java中return和finally的執行順序是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

天水市| 清徐县| 株洲市| 乌鲁木齐市| 治县。| 绥芬河市| 新营市| 兴国县| 和静县| 宜兴市| 博白县| 吉隆县| 特克斯县| 永昌县| 九江市| 濮阳市| 丰原市| 广平县| 宜丰县| 鸡西市| 新竹市| 黎城县| 石柱| 东阳市| 威海市| 晋宁县| 上犹县| 增城市| 宾川县| 昔阳县| 中宁县| 哈尔滨市| 托里县| 土默特左旗| 嘉峪关市| 江阴市| 安国市| 夏邑县| 拉孜县| 中方县| 蕉岭县|