天天看點

經典面試題,try-catch-finally在虛拟機中的實作

相信大家在面試中,或者其他情況下經常會看到這樣的一道題,下面inc()方法調用後的傳回值是什麼,答案大家自己去執行下程式或者問度娘之後應該都知道了,在方法沒有異常的時候,傳回的是1,出現Exception異常的時候傳回的是2,出現Exception以外的異常緻使方法非正常退出時,沒有傳回值。但這樣的結果在虛拟機的實作原理是什麼呢,我想很多童鞋是不知道的。

public int inc() {
    int x;
    try{
        x = 1;
        return x;
    } catch(Exception e) {
        x = 2;
        return x;
    }finally {
        x = 3;
    }

} 
           
經典面試題,try-catch-finally在虛拟機中的實作

圖1-1

如圖1-1,是我用javap -verbose執行該方法後得到的該方法對應的Class檔案的位元組碼

從Exception table可以看到在正常執行時,是從第1步開始到第7步傳回,首先将1指派第二個本地變量(第1步-第2步),這裡的第二個本地變量就對應着x,再将x複制一份存入第三個本地變量(第3步-第4步)。接着執行finally中的指派,将3指派給x存入第二個本地變量,讀取第三個本地變量到操作棧頂,即1,并調用ireturn指令以int形式傳回(第5步-第7步)。

如果報Exception,第4步執行之後将執行第8步,将2指派給x存入第二個本地變量,複制2到第四個本地變量,接着執行finally中的指派,将3指派給x存入第二個本地變量,讀取第四個本地變量到操作棧頂,即2,并調用ireturn指令以int形式傳回(第8步-第16步)。

如果出現其他狀況,将直接跳轉到第17步,将3指派給x存入第二個本地變量。将異常推送至棧頂并抛出。沒有調用ireturn,沒有傳回值。

是以,才得到上面的結論,現在童鞋們都知道 了吧= =

虛拟機位元組碼指令說明:

iconst_{i} : 将int型i推送至棧頂

istore_{i} : 将int型值存入第i+1個本地變量

iload_{i} : 将第i+1個int型本地變量推送至棧頂

ireturn : 從目前方法傳回int

astore : 将棧頂引用型數值存入指定本地變量

aload : 将指定的引用類型本地變量推送至棧頂

athrow : 将棧頂的異常抛出

繼續閱讀