1. 程式人生 > >經典面試題,try-catch-finally在虛擬機器中的實現

經典面試題,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;
    }

} 


圖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 : 將棧頂的異常丟擲