日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

从JVM指令层面看try-catch-finally返回值问题

發(fā)布時間:2025/3/21 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从JVM指令层面看try-catch-finally返回值问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

貌似很多人對下面的方法的返回值都比較迷糊:

Java代碼

  • package?cc.lixiaohui.demo;????
  • ????
  • public?class?ReturnValueTest?{????
  • ????public?int?test()?{????
  • ????????int?a;????
  • ????????try?{????
  • ????????????a?=?1;????
  • ????????????//int?b?=?1?/?0;????
  • ????????????return?a;????
  • ????????}?catch?(Exception?e)?{????
  • ????????????a?=?2;????
  • ????????????return?a;????
  • ????????}?finally?{????
  • ????????????a?=?3;????
  • ????????}????
  • ????}????
  • }??
  • ?

    test方法的返回值自然是1,如果把注釋那行去掉,那就是2.

    ?

    為什么?

    用javap -verbose ReturnValueTest 查看字節(jié)碼:

    重點查看test()方法指令: 下載

    Javap代碼

  • Compiled?from?"ReturnValueTest.java"??
  • public?class?cc.lixiaohui.demo.ReturnValueTest?extends?java.lang.Object??
  • ??SourceFile:?"ReturnValueTest.java"??
  • ??minor?version:?0??
  • ??major?version:?49???????
  • ??Constant?pool:????????--常量池??
  • const?#1?=?class????????#2;?????//??cc/lixiaohui/demo/ReturnValueTest??
  • const?#2?=?Asciz????????cc/lixiaohui/demo/ReturnValueTest;??
  • const?#3?=?class????????#4;?????//??java/lang/Object??
  • const?#4?=?Asciz????????java/lang/Object;??
  • const?#5?=?Asciz????????<init>;??
  • const?#6?=?Asciz????????()V;??
  • const?#7?=?Asciz????????Code;??
  • const?#8?=?Method???????#3.#9;??//??java/lang/Object."<init>":()V??
  • const?#9?=?NameAndType??#5:#6;//??"<init>":()V??
  • const?#10?=?Asciz???????LineNumberTable;??
  • const?#11?=?Asciz???????LocalVariableTable;??
  • const?#12?=?Asciz???????this;??
  • const?#13?=?Asciz???????Lcc/lixiaohui/demo/ReturnValueTest;;??
  • const?#14?=?Asciz???????test;??
  • const?#15?=?Asciz???????()I;??
  • const?#16?=?class???????#17;????//??java/lang/Exception??
  • const?#17?=?Asciz???????java/lang/Exception;??
  • const?#18?=?Asciz???????a;??
  • const?#19?=?Asciz???????I;??
  • const?#20?=?Asciz???????e;??
  • const?#21?=?Asciz???????Ljava/lang/Exception;;??
  • const?#22?=?Asciz???????SourceFile;??
  • const?#23?=?Asciz???????ReturnValueTest.java;??
  • ??
  • {??
  • public?cc.lixiaohui.demo.ReturnValueTest();?????--構(gòu)造方法就不分析了??
  • ??Code:??
  • ???Stack=1,?Locals=1,?Args_size=1??
  • ???0:???aload_0??
  • ???1:???invokespecial???#8;?//Method?java/lang/Object."<init>":()V??
  • ???4:???return??
  • ??LineNumberTable:??
  • ???line?8:?0??
  • ??
  • ??LocalVariableTable:??
  • ???Start??Length??Slot??Name???Signature??
  • ???0??????5??????0????this???????Lcc/lixiaohui/demo/ReturnValueTest;??
  • ??
  • ??
  • public?int?test();??
  • ??Code:??
  • ???Stack=1,?Locals=5,?Args_size=1?--?[Stack=1貌似表示棧深度為1(不確定),]Locals=5表示局部變量表長度為5,?Args_size=1表示該方法有1個參數(shù)(this)??
  • ???0:???iconst_1????????--將int值?1?壓棧??
  • ???1:???istore_1????????--將棧頂值(即1)彈出保存至局部變量表第2個位置(局部變量表下標(biāo)是從0開始的,但是0位置被this變量占用了)??
  • ???2:???iload_1?????????--將局部變量表第2個位置的值壓棧??
  • ???3:???istore??4???????--將棧頂?shù)闹祻棾霾⒈4嬷辆植孔兞勘淼?/span>5個位置(這里可以看到)??
  • ???5:???iconst_3????????--(這里開始為finally塊)將int值3壓棧??
  • ???6:???istore_1????????--將棧頂?shù)闹?#xff08;即3)彈出并存儲至局部變量表第2個位置??
  • ???7:???iload???4???????--將局部變量表第5個位置(即1)壓棧??
  • ???9:???ireturn?????????--返回棧頂?shù)闹?#xff08;即1),?結(jié)束方法調(diào)用(該路徑為try(未拋異常)?->?finally)??
  • ?????
  • ???10:??astore_2????????--將棧頂?shù)囊?#xff08;這里即為catch塊中捕捉到的異常e)存儲至局部變量表的第3個位置??
  • ???11:??iconst_2????????--將int值2壓棧??
  • ???12:??istore_1????????--將棧頂值(即2)彈出并存儲至局部變量表第2個位置??
  • ???13:??iload_1?????????--將局部變量表第2個位置的值(即2)壓棧??
  • ???14:??istore??4???????--將棧頂值彈出(即2)并保存至局部變量表第5個位置,原來第五個位置是1,現(xiàn)在1被覆蓋了,變?yōu)?/span>2??
  • ???16:??iconst_3????????--(這里開始為finally塊)將int值3壓棧??
  • ???17:??istore_1????????--將棧頂?shù)闹?#xff08;即3)彈出并存儲至局部變量表第2個位置??
  • ???18:??iload???4???????--將局部變量表第5個位置(即2)壓棧??
  • ???20:??ireturn?????????--返回棧頂?shù)闹?#xff08;即2),結(jié)束方法調(diào)用(該路徑為try(拋Exception或其子類異常)?->?catch?->?finally)??
  • ?????
  • ???21:??astore_3????????--將棧頂?shù)囊?#xff08;這里為非Exception的子類異常)存儲至局部變量表的第4個位置??
  • ???22:??iconst_3????????--將int值3壓棧??
  • ???23:??istore_1????????--將棧頂值(即3)彈出并存儲至局部變量表第二個位置??
  • ???24:??aload_3?????????--將局部變量表第4個位置(即為異常引用)壓棧??
  • ???25:??athrow??????????--將棧頂?shù)漠惓伋?該路徑為try(拋非Exception或其子類異常)?->?finally,?或者try(拋Exception或其子類異常)?->?catch(拋任何異常)?->?finally?)??
  • ??Exception?table:??
  • ???from???to??target?type??
  • ?????0?????5????10???Class?java/lang/Exception??--若執(zhí)行到0-5行(即在try塊中)拋出java.lang.Exception或其子類則跳轉(zhuǎn)至第10行執(zhí)行(即catch塊)??
  • ?????0?????5????21???any????????????????????????--若執(zhí)行到0-5行(即在try塊中)拋出非java.lang.Exception或其子類則跳轉(zhuǎn)至第21行執(zhí)行(即finally塊)??
  • ????10????16????21???any????????????????????????--若執(zhí)行到10-16行(即在catch塊中)拋出任何異常則跳轉(zhuǎn)至21行執(zhí)行(即finally塊)??
  • ??LineNumberTable:??????--這個表為源碼行數(shù)與字節(jié)碼行數(shù)的映射??
  • ???line?13:?0??
  • ???line?14:?2??
  • ???line?19:?5??
  • ???line?14:?7??
  • ???line?15:?10??
  • ???line?16:?11??
  • ???line?17:?13??
  • ???line?19:?16??
  • ???line?17:?18??
  • ???line?18:?21??
  • ???line?19:?22??
  • ???line?20:?24??
  • ??
  • ??LocalVariableTable:???????--這個即為局部變量表,?start和length結(jié)合起來就可以確定該變量的作用范圍,?例如this作用范圍為整個方法??
  • ???Start??Length??Slot??Name???Signature??
  • ???0??????26??????0????this???????Lcc/lixiaohui/demo/ReturnValueTest;???--占用第1個slot(一個slot應(yīng)該是32bits)??
  • ???2??????8??????1????a???????I?????????????????????????????????????????--I標(biāo)識int,?占用第2個slot??
  • ???13??????8??????1????a???????I????????????????????????????????????????--占用第2個slot??
  • ???24??????2??????1????a???????I????????????????????????????????????????--占用第2個slot??
  • ???11??????10??????2????e???????Ljava/lang/Exception;???????????????????--占用第3個slot??
  • ??
  • ??
  • }??
  • ?

    可以發(fā)現(xiàn)jvm始終把返回值放在最后一個局部變量表的位置,而且在finally中改變x并不影響返回值.

    轉(zhuǎn)載于:https://my.oschina.net/u/2978057/blog/769725

    總結(jié)

    以上是生活随笔為你收集整理的从JVM指令层面看try-catch-finally返回值问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。