相信大家在面試中,或者其他情況下經常會看到這樣的一道題,下面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 : 将棧頂的異常抛出