trt catch finally 的字節(jié)碼分析

先上源碼:

public class TestRef {

    public static void main(String[] args) {
        int c = count(0, 20);
        System.out.println(c);
    }


    public static int count(int a, int b) {
        try {
            return add(a, b);
        } catch (RuntimeException e) {
            e.printStackTrace();
            return 0;
        } finally {
            System.out.println("回收資源");
        }
    }

    private static int add(int a, int b) {
        if (a == 0) {
            throw new RuntimeException();
        }
        return a + b;
    }
}

再看字節(jié)碼

{
  public static void main(java.lang.String[]);
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_0                  //將常量0推到棧頂
         1: bipush        20        //將直接操作數(shù)20 推到棧頂
         3: invokestatic  #2                  // Method count:(II)I 使用前2行推入的參數(shù)調(diào)用count靜態(tài)方法
         6: istore_1                       //將count方法的結(jié)果存到局部變量表1號(hào)位 
         7: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        10: iload_1                       
        11: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V 7、10闷畸、11三行是輸出count的結(jié)果
        14: return

  public static int count(int, int);
    Code:
      stack=2, locals=5, args_size=2
         0: iload_0        //加載局部變量表0號(hào)位到棧頂  靜態(tài)方法沒(méi)有this 局部變量表從0開(kāi)始存
         1: iload_1        //加載局部變量表1號(hào)位到棧頂 
         2: invokestatic  #5                  // Method add:(II)I  調(diào)用靜態(tài)方法 add
         5: istore_2                //將棧頂元素存到局部變量表2號(hào)位,這里是存add結(jié)果
         6: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         9: ldc           #6                  // String 回收資源
        11: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V 6、9乎完、11三行是finally塊
        14: iload_2    //將局部變量2號(hào)位載入棧頂
        15: ireturn    //返回棧頂int類(lèi)型元素 
        16: astore_2    //將對(duì)象引用存到局部變量表2號(hào)位
        17: aload_2      //加載局部變量表2號(hào)位的對(duì)象引用到棧頂
        18: invokevirtual #9                  // Method java/lang/RuntimeException.printStackTrace:()V
        21: iconst_0    //推送常量0到棧頂
        22: istore_3    //存儲(chǔ)棧頂元素到局部變量表3號(hào)位
        23: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        26: ldc           #6                  // String 回收資源  加載運(yùn)行時(shí)常量池#6到棧頂
        28: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        31: iload_3    
        32: ireturn
        33: astore        4
        35: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        38: ldc           #6                  // String 回收資源
        40: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        43: aload         4
        45: athrow    //拋出異常
      Exception table:
         from    to  target type
             0     6    16   Class java/lang/RuntimeException
             0     6    33   any
            16    23    33   any
            33    35    33   any

  public static int add(int, int);
    Code:
      stack=2, locals=2, args_size=2
         0: iload_0 
         1: ifne          12   //如果棧頂元素小于0跳轉(zhuǎn)到12行
         4: new           #8                  // class java/lang/RuntimeException
         7: dup   //復(fù)制上一個(gè)元素。new對(duì)象后一般都有這一步品洛。因?yàn)槌跏蓟瘜?duì)象會(huì)消耗一個(gè)引用
         8: invokespecial #10                 // Method java/lang/RuntimeException."<init>":()V
        11: athrow
        12: iload_0
        13: iload_1
        14: iadd
        15: ireturn
}

count方法相當(dāng)?shù)膹?fù)雜 按順序看 是肯定不行的树姨。 得結(jié)合Exception table異常表來(lái)看摩桶。異常表的順序是對(duì)應(yīng)catch的。from 0 to 6表示的是0-5這幾行帽揪,不含6的硝清。

0-5行做的是add(a, b); 6-11行是finally塊 14,15行是返回add方法的值转晰。這是沒(méi)有異常的時(shí)候的執(zhí)行流程芦拿。

異常表有2個(gè)from 0 to 6 的catch 第一個(gè)是我們定義的RuntimeException第二個(gè)是any 代表所有類(lèi)型的異常。 這2個(gè)catch 的處理方法是不一樣的查邢。target就是處理行開(kāi)始蔗崎。如果在0-5行發(fā)生運(yùn)行時(shí)異常,就跳到16行處理扰藕。 16行 astore_2 將棧頂元素存儲(chǔ)到2號(hào)位缓苛,這里的棧頂元素是e 就是jvm傳入的異常對(duì)象的引用,16-32行 可以看做是一個(gè)塊邓深,打印異常棧未桥,調(diào)用finally返回元素0(0在調(diào)用finally 之前已經(jīng)存入了局部變量表,但是在執(zhí)行了finnaly之后才從局部變量表取出返回) 這里可以發(fā)現(xiàn)沒(méi)有使用任何的跳轉(zhuǎn)語(yǔ)句 比如 goto jsr ret 所以finally的代碼塊相當(dāng)于重復(fù)了一次庐完。

第三個(gè)catch from 16 to 23 這就是 catch (RuntimeException e) 里面的代碼钢属,只是不含返回,如果這里發(fā)生了異常會(huì)跳轉(zhuǎn)到33行去執(zhí)行门躯。33行是保存異常對(duì)象引用淆党,然后35-40行又是finally的內(nèi)存,讶凉,然后43-45 就是把異常拋出到上層了染乌。第三次重復(fù)finally

第四個(gè)catch是from 33 to 35,這中間只有一行代碼就是33的 astore 4 如果這行發(fā)生異常懂讯,會(huì)不斷的重試荷憋。不斷的跳回到33這行。成功后做的事情就和第三個(gè)catch一樣了褐望。

第2勒庄、3、4 3個(gè)catch都是隱式的 幫我們做了 沒(méi)有用代碼寫(xiě)出來(lái)的內(nèi)容:拋出未catch異常到上層

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瘫里,一起剝皮案震驚了整個(gè)濱河市实蔽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谨读,老刑警劉巖局装,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡铐尚,警方通過(guò)查閱死者的電腦和手機(jī)拨脉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宣增,“玉大人玫膀,你說(shuō)我怎么就攤上這事⊥骋ǎ” “怎么了匆骗?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)誉简。 經(jīng)常有香客問(wèn)我,道長(zhǎng)盟广,這世上最難降的妖魔是什么闷串? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮筋量,結(jié)果婚禮上烹吵,老公的妹妹穿的比我還像新娘。我一直安慰自己桨武,他們只是感情好肋拔,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著呀酸,像睡著了一般凉蜂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上性誉,一...
    開(kāi)封第一講書(shū)人閱讀 52,184評(píng)論 1 308
  • 那天窿吩,我揣著相機(jī)與錄音,去河邊找鬼错览。 笑死纫雁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的倾哺。 我是一名探鬼主播轧邪,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼羞海!你這毒婦竟也來(lái)了忌愚?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扣猫,失蹤者是張志新(化名)和其女友劉穎菜循,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡癌幕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年衙耕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勺远。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡橙喘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出胶逢,到底是詐尸還是另有隱情厅瞎,我是刑警寧澤,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布初坠,位于F島的核電站和簸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏碟刺。R本人自食惡果不足惜锁保,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望半沽。 院中可真熱鬧爽柒,春花似錦、人聲如沸者填。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)占哟。三九已至心墅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間重挑,已是汗流浹背嗓化。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谬哀,地道東北人刺覆。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像史煎,于是被迫代替她去往敵國(guó)和親谦屑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法篇梭,類(lèi)相關(guān)的語(yǔ)法氢橙,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法恬偷,異常的語(yǔ)法悍手,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,660評(píng)論 18 399
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器坦康,智...
    卡卡羅2017閱讀 134,695評(píng)論 18 139
  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,345評(píng)論 0 10
  • Archlinux installation guidehttps://wiki.archlinux.org/in...
    sthtodo閱讀 1,685評(píng)論 1 6
  • 毛浴巾無(wú)色系陳列竣付;在紗布和毛圈的區(qū)分之后,對(duì)毛巾做冷暖色系的區(qū)分陳列 衛(wèi)生巾縱向?qū)R滞欠,整齊度要加強(qiáng) 床品的疊裝有大...
    Holiday澈閱讀 400評(píng)論 0 0