关于try中含有return语句的执行顺序的升入解析(学习javap命令)

今天看到有几个帖子是讲try/finally语句中try语句体包含return语句的执行顺序问题,我做了一下深入的了解,下面进行分析
首先,来看一段代码:
  1. public class TestTryFinally {
  2. public static void main(String[] args) {
  3.   test();
  4. }
  5. public static void test() {
  6.   int x = 5;
  7.   try{
  8.    System.out.println("try 语句-----x值:"+x);
  9.   }finally{
  10.    x++;
  11.    System.out.println("finally 语句-----x值:"+x);
  12.   }
  13. }
  14. }
复制代码
想必大家都很清楚这段代码的输出结果,对的,这段代码的输出结果是:
try 语句-----x值:5
finally 语句-----x值:6
先执行try语句体,再执行finally语句体,现在,代码稍微改动一下
  1. public class TestTryFinally {
  2. public static void main(String[] args) {
  3.   System.out.println(test());
  4. }
  5. public static int test() {
  6.   int x = 5;
  7.   try{
  8.    return x;
  9.   }finally{
  10.    x++;
  11.    System.out.println("finally 语句-----x值:"+x);
  12.   }
  13. }
  14. }
复制代码
大家再看输出结果是什么呢?是不是大多数人认为结果如下呢:
finally 语句-----x值:6
6
   实际上,结果如下:
finally 语句-----x值:6

5

这该怎么解释呢,既然先执行了finally里的语句,那么x的值应该改变了的,可是为什么try里面返回的值还是原来的那个呢,这个问题可以通过反编译查看字节码指令来解释。(为了更加简洁字节码,这里把上面代码中的finally区域里的打印语句省掉)

然后通过如下指令得到字节码:javap -c TestTryFinally
或者在eclipse下用断点解决
得到的字节码如下:
直接看test方法的字节码

0:iconst_5   //将int型的5入栈

1:istore_0   //将int类型值存入局部变量0

2:iload_0    //从局部变量0中装载int类型值(装入5)

3:istore_1  //将int类型值存入局部变量1(这一句等于就是把5又放入到索引为1的变量中去)

4:iinc   0,1   //把局部变量区索引为0的变量加1(在这里就是执行finally语句体中的x++)

5:iload_1   //从局部变量1中装载int类型值(装入局部变量1中的值,这个值为5)

6:ireturn   //从方法中返回int类型数据(返回5)

7://后面的就是抛出异常时的代码,这里就不进行分析

从分析字节码可以看出,在try语句返回之前先将x存入到另一个变量中,再进行finally里面的语句(x++)

在finally里面语句执行完成后,再从之前的变量里取出值5,所以不管你在finally里怎么改变x的值,try里返回的

已经不会改变了。

现在,就已经可以对这段代码有一个比较深的理解了。

总结:如果try中有return语句时(注:finally语句体中没有return语句)当执行到return语句时,先把要return的值

存放在另一个新建的变量中,在finally里执行完后,再从刚才新建的变量中取出值进行返回。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值