经典面试题,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 : 将栈顶的异常抛出


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值