黑马程序员技术交流社区

标题: 一个疑惑 [打印本页]

作者: 张吉日    时间: 2012-10-18 12:58
标题: 一个疑惑
本帖最后由 张吉日 于 2012-10-18 16:48 编辑

为什么finally里面的n--之后 try里面的return  n的值没有--    这里面是什么原理
  1. public class Demo {
  2.         /*
  3.          * mian函数,程序的入口
  4.          */
  5.         public static void main(String[] args){
  6.                 System.out.println(function());
  7.         }
  8.         /*
  9.          * 定义功能方法
  10.          */
  11.         public static int function(){
  12.                
  13.                 int n = 5;                                        // 定义局部变量
  14.                
  15.                 try{
  16.                
  17.                                                                         // 定义返回值
  18.                         return n;                                // 运行结果n的值没有改变,还是 5
  19.                 }
  20.                 finally{
  21.                         n--;                                        // 将n--之后的值打印出来。
  22.                         
  23.                         System.out.println(n);        // n的值 打印是4
  24.                 }
  25.         }
  26. }
复制代码

作者: 徐梦侠    时间: 2012-10-18 13:06
需要理解这个程序try和finally的执行顺序。
当我们把try中数据运算出来,到return 的时候,它会先把得到的n放在主函数那儿,然后就不运行了,先运行finally的代码,当finally的代码运行完后,就再运行return的代码,但是n的值还是原来那个,并不是finally后面的。

作者: 王威    时间: 2012-10-18 13:22
本帖最后由 王威 于 2012-10-18 13:33 编辑
  1. public class Demo {
  2.         /*
  3.          * mian函数,程序的入口
  4.          */
  5.         public static void main(String[] args){
  6.                 System.out.println(function());
  7.         }
  8.         /*
  9.          * 定义功能方法
  10.          */
  11.         public static int function(){
  12.                
  13.                 int n = 5;                                        // 定义局部变量
  14.                
  15.                 try{
  16.                      return n;                                // 运行结果n的值没有改变,还是 5
  17.                 }
  18.                 finally{
  19.                         n--;                                        // 将n--之后的值打印出来。
  20.                         System.out.println(n);        // n的值 打印是4
  21.                 }
  22.         }
  23. }
复制代码
我给你的代码设了个断点,debug跟踪了一下,发现执行完finally里面的语句后
然后再执行main()方法里打印语句的时候System.out.println(function()); ,我跟进去看了下,
这个输出语句传进去的参数是5,说明当执行try语句时n=5已经返回去了只是没有打印出来而已,先等
finally执行完以后再来打印。
也就是说,如果try语句体中含有return语句,就会把要return的值存放在一个不同于n的变量中,当finally执行完后
再从中取出值,所以你在finally中改变n的值不会影响try中要返回的值,因为这是从先前保存的另一个不同于n的变量中取得的
作者: 丁旭    时间: 2012-10-18 13:24
当运行到try块中return语句时,n的值会保留。然后跳到finally块中执行里面的语句,执行完毕后,回到return运行。finally中的n值不会影响try块中的。
作者: 葬天    时间: 2012-10-18 13:36
本帖最后由 葬天 于 2012-10-18 13:40 编辑

参考《 The JavaTM Virtual Machine Specification, Second Edition 》中 7.13 节 Compiling finally

Java 虚拟机编译 finally 语句块时,实际上,Java 虚拟机会把 finally 语句块作为 subroutine,直接插入到 try 语句块或者 catch 语句块的控制转移语句之前。但是,还有另外一个不可忽视的因素,那就是在执行 subroutine(也就是 finally 语句块)之前,try 或者 catch 语句块会保留其返回值到本地变量表(Local Variable Table)中。待 subroutine 执行完毕之后,再恢复保留的返回值到操作数栈中,然后通过 return 或者 throw 语句将其返回给该方法的调用者(invoker)。
作者: 曾浩    时间: 2012-10-18 14:06
这就是一个返回值压栈出栈的问题
1.首先是执行try中的语句当执行到return时 n的值还没有改变 但这时返回值被压栈了(也就是存储到了一个临时的空间中了)
2.然后再执行finally中的语句 finally中执行完后 并没有改变返回值因为他另存到一个空间了
3.返回值出栈
作者: 王震阳老师    时间: 2012-10-18 14:13
给楼主一个最完整的答复吧,这个问题是这样的:当java程序执行try块、catch块时遇到了return或throw语句,这两个语句都会导致该方法立即结束,但是系统执行这两个语句并不会结束该方法,而是去寻找该异常处理中的finally块,如果没有finally块,程序立即执行return或throw语句,方法终止。如果有finally块,系统立即开始执行finally块,只有当finally块执行完成后,系统才会再次跳回来执行try块、catch块里的return或throw语句。如果finally块里也使用了return或它throw等导致方法终止的语句,finally块已经终止了方法,系统将不会跳回去执行try、catch块里的任何代码。
作者: 张吉日    时间: 2012-10-18 16:48
王威 发表于 2012-10-18 13:22
我给你的代码设了个断点,debug跟踪了一下,发现执行完finally里面的语句后
然后再执行main()方法里打印语 ...

是Myeclipse里面的断点吗,我懂了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2