黑马程序员技术交流社区
标题:
一个疑惑
[打印本页]
作者:
张吉日
时间:
2012-10-18 12:58
标题:
一个疑惑
本帖最后由 张吉日 于 2012-10-18 16:48 编辑
为什么finally里面的n--之后 try里面的return n的值没有-- 这里面是什么原理
public class Demo {
/*
* mian函数,程序的入口
*/
public static void main(String[] args){
System.out.println(function());
}
/*
* 定义功能方法
*/
public static int function(){
int n = 5; // 定义局部变量
try{
// 定义返回值
return n; // 运行结果n的值没有改变,还是 5
}
finally{
n--; // 将n--之后的值打印出来。
System.out.println(n); // n的值 打印是4
}
}
}
复制代码
作者:
徐梦侠
时间:
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 编辑
public class Demo {
/*
* mian函数,程序的入口
*/
public static void main(String[] args){
System.out.println(function());
}
/*
* 定义功能方法
*/
public static int function(){
int n = 5; // 定义局部变量
try{
return n; // 运行结果n的值没有改变,还是 5
}
finally{
n--; // 将n--之后的值打印出来。
System.out.println(n); // n的值 打印是4
}
}
}
复制代码
我给你的代码设了个断点,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