成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java中return和finally到底哪個先執行

開發 后端
本章節我們從字節碼的角度來探究下return和finally到底哪個先執行。下面先來看一段簡單地源碼。

[[348914]]

本章節我們從字節碼的角度來探究下return和finally到底哪個先執行。下面先來看一段簡單地源碼:

 

  1. public class ReturnFinallyDemo { 
  2.     public static void main(String[] args) { 
  3.         System.out.println(case1()); 
  4.     } 
  5.  
  6.     public static int case1() { 
  7.         int x; 
  8.         try { 
  9.             x = 1; 
  10.             return x; 
  11.         } finally { 
  12.             x = 3; 
  13.         } 
  14.     } 
  15.  
  16. # 輸出 

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

 

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

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

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

 

  1. public static int case2() { 
  2.     int x; 
  3.     try { 
  4.         x = 1; 
  5.         return ++x; 
  6.     } finally { 
  7.         x = 3; 
  8.     } 
  9.  
  10. # 輸出 

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

 

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

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

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

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

 

  1. public static int case3() { 
  2.     int x; 
  3.     try { 
  4.         x = 1; 
  5.         return ++x; 
  6.     } finally { 
  7.         x = 3; 
  8.         return x; 
  9.     } 
  10. # 輸出 

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

 

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

從字節碼以及解釋來看,直接忽略了try語句塊中的return指令,這樣的代碼會讓人產生疑惑,所以平時不建議這么寫。本章節就到這里了。

責任編輯:未麗燕 來源: 今日頭條
相關推薦

2017-03-02 14:52:46

2023-12-18 13:10:00

finally死鎖JVM 崩潰

2023-05-28 13:03:46

BeegoGin設計

2019-07-27 09:40:56

MySQLPG數據庫

2022-10-11 10:18:12

數據硬盤開機

2020-06-28 09:08:08

Java語法塊開發

2024-07-10 10:54:44

2021-08-06 22:47:37

編程語言數據工具

2021-03-19 07:40:22

緩存數據庫日志

2020-06-08 11:30:04

PGMySQL數據庫

2024-11-19 08:10:00

2021-03-27 10:56:17

promisethenfinally

2021-09-07 13:15:01

語言return 1return 0

2012-06-02 00:53:39

Javafinally

2021-01-13 05:23:27

緩存數據庫高并發

2021-07-26 08:12:31

開源API網關

2025-01-22 09:21:46

2025-06-12 09:16:54

2022-08-27 14:42:45

Java集合數組
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品视频网址 | 日韩精品欧美精品 | 天天欧美 | 在线观看国产视频 | 一区二区三区国产精品 | 精品国产黄a∨片高清在线 www.一级片 国产欧美日韩综合精品一区二区 | 狠狠av| 久久精品av麻豆的观看方式 | 中文字幕亚洲视频 | 黄频免费| 一级片在线观看 | 四虎成人精品永久免费av九九 | 91传媒在线观看 | 亚洲精品在线免费 | h免费观看 | 亚洲精品一区二区网址 | 欧美成视频在线观看 | 国产成人在线一区二区 | 久久久久久国产精品久久 | 欧美黄色免费网站 | 亚洲97| 亚洲精品99 | 午夜精品一区二区三区免费视频 | 蜜臀av日日欢夜夜爽一区 | 一区二区三区视频在线观看 | 北条麻妃一区二区三区在线视频 | 欧美激情一区 | 中文成人在线 | 在线观看视频91 | 日韩在线欧美 | 成人一区二区三区在线观看 | 国产高清在线视频 | 久久久影院 | 国产分类视频 | 久久久www | 99热在线免费 | 免费一二区 | 欧美日韩福利 | 91精品成人久久 | 99久久国产精 | 久久一区视频 |