黑马程序员技术交流社区

标题: 关于finally与return的执行顺序问题 [打印本页]

作者: rookiefly    时间: 2015-10-29 22:50
标题: 关于finally与return的执行顺序问题
大家都知道finally语句块是在return语句之前完成的,那么谁能解释一下下面的现象呢?请看代码:
public class FinallyReturnDemo
{
        public static void main(String[] args)
        {
                System.out.println("main: "+test());
        }
        
        private static int test(){
                int x = 1;
                try{
                        System.out.println("try: x = "+x);
                        return x;
                }catch(Exception e){
                        throw new RuntimeException(e);
                }finally{
                        ++x;
                        System.out.println("finally: x = "+x);
                }
        }
}

执行结果大家猜猜是多少?









作者: 新火燎塬521    时间: 2015-10-29 22:50
我自己有Debug看看执行顺序,发现顺序执行try 里面的return x 然后下一步跳到finally 执行完finally后 又跳到try里面的return 接着返回main
http://www.cnblogs.com/forcertain/archive/2012/11/22/2782855.html  可以看看这个
作者: rookiefly    时间: 2015-10-29 22:52
执行结果:
try: x = 1
finally: x = 2
main: 1
请按任意键继续. . .  
作者: rookiefly    时间: 2015-10-29 22:54
为什么上传不了图片呢?添加代码的时候也是没有格式的,有没有解决方法啊?
作者: zhangdazhi186    时间: 2015-10-30 00:11
结果是这个 有什么问题吗?
try: x = 1
finally: x = 2
main: 1
那个return 是整个方法执行完了才把值返回去的,并不是执行到try 的时候就马上返回去的。
作者: uknow    时间: 2015-10-30 00:32
执行到return的时候,x的值是1,此时内存中会有一个路径产生,该路径的返回值时1,但是return下面还有一个finally代码块,所以先执行finally代码块,代码块执行完后再返回以前的执行路径,将x=1返回。
作者: rookiefly    时间: 2015-10-30 08:10
zhangdazhi186 发表于 2015-10-30 00:11
结果是这个 有什么问题吗?
try: x = 1
finally: x = 2

在finally执行完了之后x的值已经变成2了,按照你说的那样主函数接受的返回值应该是2猜对啊,
作者: zhangdazhi186    时间: 2015-10-30 09:14
执行到try 里面的return 的时候  就已经把x=1的值 作为回传参数了,只是这test() 方法还没执行完还需继续往下走,等整个test()都走完了,那个回传的参数才传给主函数。
作者: 新火燎塬521    时间: 2015-10-30 10:00
  private static int test(){}这个是带返回值的方法,返回的是int型数据,这个数据一定是取自方法内return后面的数字,只有在try的时候返回了数据,而在最后执行finally的时候没有返回数,所以这个带返回值的函数最后的那个值就是try里面返回去的。如果在finally里面加一句 return x;那么test()才会得到x=2。
作者: 新火燎塬521    时间: 2015-10-30 10:03
新火燎塬521 发表于 2015-10-30 10:00
private static int test(){}这个是带返回值的方法,返回的是int型数据,这个数据一定是取自方法内return ...

可以假设有一个变量在存储这个带返回值的函数返回去的值,当函数体执行完成之后,这个变量会代替这个函数,把存储的值交给调用它的地方。而这个值只接受函数中return后面的数据
作者: _let'sgo    时间: 2015-10-30 11:08
可以这么理解吧:try里边return x,返回的不是变量x,而是其值 1,所以执行完finally后x变化,但return的还是1,不会变化
作者: kernel    时间: 2015-10-30 12:05
return 返回临时temp值,finally中的操作还是要执行的
作者: luhaisheng    时间: 2015-10-30 14:13
try: x = 1 finally: x = 2 main: 1    在try catch 语句块中虽然有return  但是finally语句块是必须执行的
作者: 菊花爆满山    时间: 2015-10-30 14:57
其实在执行finally语句块之前就已经确定返回值的是1了 虽然执行完finally语句块后x的值是2 但不会改变返回值
作者: rookiefly    时间: 2015-10-30 16:11
uknow 发表于 2015-10-30 00:32
执行到return的时候,x的值是1,此时内存中会有一个路径产生,该路径的返回值时1,但是return下面还有一个f ...

是在执行到return的时候又开启了一个线程吗?一个线程返回值,一个线程用于继续执行finally代码块?
作者: rookiefly    时间: 2015-10-30 16:20
uknow 发表于 2015-10-30 00:32
执行到return的时候,x的值是1,此时内存中会有一个路径产生,该路径的返回值时1,但是return下面还有一个f ...

我觉得你这个还是有说服力的,在finally中加入return 2,结果main中接受的是2 是不是说finally中的return产生的路径把try中的return给短路了?或者两个return后的返回值指向一个地址或变量。
作者: rookiefly    时间: 2015-10-30 16:25
新火燎塬521 发表于 2015-10-30 10:03
可以假设有一个变量在存储这个带返回值的函数返回去的值,当函数体执行完成之后,这个变量会代替这个函数 ...

恩,这个解释听着挺靠谱的,那这个值是在finally执行之前就返回了吗?还是执行之后返回啊?
作者: 大自然的搬运工    时间: 2015-10-30 18:51
这是一道测试题吧 。。。。。
作者: xingjiyuan26    时间: 2015-10-30 19:04
rookiefly 发表于 2015-10-30 16:20
我觉得你这个还是有说服力的,在finally中加入return 2,结果main中接受的是2 是不是说finally中的return ...

可以理解成短路了,返回的是temp值,这个值是在return时返回的,也就是在return时复制了一份值。但是return前如果有finally,则会最后执行一下finally代码块里的内容。这时,finally里没有return语句,所以这个temp值没有发生变化,所以最后打印为1。
相反,如果finally里的return语句,就会更新temp值返回,最后就会打印2
作者: rookiefly    时间: 2015-10-30 21:14
新火燎塬521 发表于 2015-10-29 22:50
我自己有Debug看看执行顺序,发现顺序执行try 里面的return x 然后下一步跳到finally 执行完finally后 又 ...

额,差不多搞明白了,不过还有一点,返回值是在执行finally代码块之前已经回了还是执行了finally之后后返回啊?会不会是自己直接返回,同时又开了一个线程用于执行finally代码块,所以导致这样的?
作者: 刘印    时间: 2015-10-31 00:24
新火燎塬521 发表于 2015-10-30 10:03
可以假设有一个变量在存储这个带返回值的函数返回去的值,当函数体执行完成之后,这个变量会代替这个函数 ...

你是哈尔滨黑马的?
作者: rookiefly    时间: 2015-10-31 09:32
刘印 发表于 2015-10-31 00:24
你是哈尔滨黑马的?

我还不是黑马的,我准备放假了去北京黑马,
作者: 新火燎塬521    时间: 2015-10-31 12:03
rookiefly 发表于 2015-10-30 21:14
额,差不多搞明白了,不过还有一点,返回值是在执行finally代码块之前已经回了还是执行了finally之后后返 ...

http://javcoder.iteye.com/blog/1131003   再看看这个 ,如果你想弄清楚,估计需要看JVM是怎么处理这些语句的
作者: 洛克先生EN    时间: 2015-11-3 18:47
return把结果返回给Test方法的啊,然后你main方法调用的Test啊




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