/**

* try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,还是在return之后执行?

*/

public class TestC {

  public static void main(String[] args) {

      System.out.println("结果: " + new TestC().test());

  }

  static int test(){

      int i = 1;

      try {

          System.out.println("try里面的i : " + i);

          return i;

      }finally{

          System.out.println("进入finally...");

          i = i+111;

          System.out.println("fianlly里面的i : " + i);

      }

  }

}


程序运行的结果为:

1533882962(1).jpg

其实 按照之前的思想觉得 返回的应该是  112  不应该是1 ,  但查资料发现

finally语句是一定会执行,但他们的执行顺序是怎么样的呢?他们的执行顺序如下:

1、执行:expression,计算该表达式,结果保存在操作数栈顶;

2、执行:操作数栈顶值(expression的结果)复制到局部变量区作为返回值;

3、执行:finally语句块中的代码;

4、执行:将第2步复制到局部变量区的返回值又复制回操作数栈顶;

5、执行:return指令,返回操作数栈顶的值;

在第一步执行完毕后,整个方法的返回值就已经确定了,由于还要执行finally代码块,因此程序会将返回值暂存在局部变量区,腾出操作数栈用来执行finally语句块中代码,等finally执行完毕,再将暂存的返回值又复制回操作数栈顶。所以无论finally语句块中执行了什么操作,都无法影响返回值,所以试图在finally语句块中修改返回值是徒劳的。因此,finally语句块设计出来的目的只是为了让方法执行一些重要的收尾工作,

而不是用来计算返回值的。所以在finally中更改返回值是无效的,因为它只是更改了操作数栈顶端复制到局部变量区的快照,并不能真正的更改返回值,但是如果在

finally中使用return的话则是会将新的操作数栈的顶端数据返回,而不是之前复制到局部变量区用作返回内容快照的值返回,所以这样是可以返回的,同样的在cathch语句块里也是这样,只有重新出现了return才有可能更改返回值