try-catch-finally-return返回值问题

    今天在看《深入java虚拟机》第六章时书中一段代码引起了我对try-catch-finally-return关系的兴趣和思考,闲话不多说直接进入主题,请看下面代码:

   代码清单1:

   public staticint inc() {

      int x;

      try {

        x = 1;

        return x;

      }catch (Exception e) {

        x = 2;

        //return x/0;

      }finally {

        x = 3;

      }

      return x;

   }

   publicstatic void main(String[] args) {

      System.out.println(inc());

   }

    执行清单1代码输出 :1

    对上面的执行过程分析如下:

    1.首先顺序执行try中的语句,当执行到return时,若return后面的表达式没有发生异常则将return后面的表达式结果计算好后复制一份副本到最后一个本地变量表的slot中(这个slot里面的值在return指令执行前将会被重新读到操作栈顶,作为方法返回值,为了讲解方便,笔者给这个slot取名为returnValue),在本例中将x=1的值1保存到returnValue中,然后转入到步骤3执行finally代码。若遇到异常则转入步骤2。

    2.顺序执行catch中代码,若遇到return,则计算完return后面的表达式后将值副本保存到returnValue中然后转入步骤3。在本例中有return此时returnValue中的值修改为2。

    3.顺序执行finally代码块中代码,在本例中此时将x赋值为3,因为没有遇到return所以不会改变returnValue中保存的原来的副本,若finally里面强加了return,则会修改returnValue中的值为当前return后面表达式的结果的副本。然后执行return将刚才修改的returnValue的值读到操作栈顶返回。此时程序结束,不会再回到try中return。在本例中finaly代码块中没有return,所以returnValue中的值仍为1。finaly代码块执行完后回到try中return将returnValue中保存的值读到操作栈顶。然后返回,本例中returnValue中保存值为1因此返回1.若try中发生异常则会转入到catch代码块中,顺序执行遇到return则修改returnValue中的值没有return则不做修改,catch中代码执行完后转入finally代码块中执行,当catch中遇到return时执行完return。

    上面的分析其实最核心的内容即为:遇到return就将计算return后面表达式的值保存到returnValue中,是异常就保存异常信息,最后返回的结果总是取最后一次保存到returnValue中的值。

    再看若将inc()方法修改为如代码清单2:

   public staticint inc() {

      int x;

      try {

         x = 1;

        return x/0;

      }catch (Exception e) {

         x = 2;

        return x;

      }finally {

         x = 3;

      }

}

    执行结果为:2

    代码清单2过程分析:当执行try中return后面的x/0时出错,此时将会把异常保存到returnValue中,然后跳转到catch中,此时x=2,在catch中遇到return,此时将2保存到returnValue中,即此时栈顶的值为2,然后执行finally代码,最后返回时取出returnValue栈顶的值即2返回。

    再看代码清单3:

   public staticint inc() {

      int x;

      try {

         x = 1;

        return x/0;

      }catch (Exception e) {

         x = 2;

        return x/0;

      }finally {

         x = 3;

      }

   }

   输出结果:

   Exceptionin thread "main"java.lang.ArithmeticException: / by zero

   at com.java.basic.returnTest.TestReturn.inc(TestReturn.java:53)

   atcom.java.basic.returnTest.TestReturn.main(TestReturn.java:42)

   显然最后一次returnValue中保存的是异常,因此程序执行时将栈顶的异常抛出,程序结束。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值