A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© rookiefly 中级黑马   /  2015-10-29 22:50  /  6655 人查看  /  23 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

5黑马币
大家都知道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);
                }
        }
}

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








23 个回复

正序浏览
return把结果返回给Test方法的啊,然后你main方法调用的Test啊
回复 使用道具 举报
rookiefly 发表于 2015-10-30 21:14
额,差不多搞明白了,不过还有一点,返回值是在执行finally代码块之前已经回了还是执行了finally之后后返 ...

http://javcoder.iteye.com/blog/1131003   再看看这个 ,如果你想弄清楚,估计需要看JVM是怎么处理这些语句的
回复 使用道具 举报
刘印 发表于 2015-10-31 00:24
你是哈尔滨黑马的?

我还不是黑马的,我准备放假了去北京黑马,
回复 使用道具 举报
刘印 来自手机 黑马帝 2015-10-31 00:24:10
20#
新火燎塬521 发表于 2015-10-30 10:03
可以假设有一个变量在存储这个带返回值的函数返回去的值,当函数体执行完成之后,这个变量会代替这个函数 ...

你是哈尔滨黑马的?
回复 使用道具 举报
新火燎塬521 发表于 2015-10-29 22:50
我自己有Debug看看执行顺序,发现顺序执行try 里面的return x 然后下一步跳到finally 执行完finally后 又 ...

额,差不多搞明白了,不过还有一点,返回值是在执行finally代码块之前已经回了还是执行了finally之后后返回啊?会不会是自己直接返回,同时又开了一个线程用于执行finally代码块,所以导致这样的?
回复 使用道具 举报
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
回复 使用道具 举报
这是一道测试题吧 。。。。。
回复 使用道具 举报
新火燎塬521 发表于 2015-10-30 10:03
可以假设有一个变量在存储这个带返回值的函数返回去的值,当函数体执行完成之后,这个变量会代替这个函数 ...

恩,这个解释听着挺靠谱的,那这个值是在finally执行之前就返回了吗?还是执行之后返回啊?
回复 使用道具 举报
uknow 发表于 2015-10-30 00:32
执行到return的时候,x的值是1,此时内存中会有一个路径产生,该路径的返回值时1,但是return下面还有一个f ...

我觉得你这个还是有说服力的,在finally中加入return 2,结果main中接受的是2 是不是说finally中的return产生的路径把try中的return给短路了?或者两个return后的返回值指向一个地址或变量。
回复 使用道具 举报
uknow 发表于 2015-10-30 00:32
执行到return的时候,x的值是1,此时内存中会有一个路径产生,该路径的返回值时1,但是return下面还有一个f ...

是在执行到return的时候又开启了一个线程吗?一个线程返回值,一个线程用于继续执行finally代码块?
回复 使用道具 举报
其实在执行finally语句块之前就已经确定返回值的是1了 虽然执行完finally语句块后x的值是2 但不会改变返回值
回复 使用道具 举报
try: x = 1 finally: x = 2 main: 1    在try catch 语句块中虽然有return  但是finally语句块是必须执行的
回复 使用道具 举报
kernel 初级黑马 2015-10-30 12:05:37
11#
return 返回临时temp值,finally中的操作还是要执行的
回复 使用道具 举报
可以这么理解吧:try里边return x,返回的不是变量x,而是其值 1,所以执行完finally后x变化,但return的还是1,不会变化
回复 使用道具 举报
新火燎塬521 发表于 2015-10-30 10:00
private static int test(){}这个是带返回值的方法,返回的是int型数据,这个数据一定是取自方法内return ...

可以假设有一个变量在存储这个带返回值的函数返回去的值,当函数体执行完成之后,这个变量会代替这个函数,把存储的值交给调用它的地方。而这个值只接受函数中return后面的数据
回复 使用道具 举报
  private static int test(){}这个是带返回值的方法,返回的是int型数据,这个数据一定是取自方法内return后面的数字,只有在try的时候返回了数据,而在最后执行finally的时候没有返回数,所以这个带返回值的函数最后的那个值就是try里面返回去的。如果在finally里面加一句 return x;那么test()才会得到x=2。
回复 使用道具 举报
执行到try 里面的return 的时候  就已经把x=1的值 作为回传参数了,只是这test() 方法还没执行完还需继续往下走,等整个test()都走完了,那个回传的参数才传给主函数。
回复 使用道具 举报
zhangdazhi186 发表于 2015-10-30 00:11
结果是这个 有什么问题吗?
try: x = 1
finally: x = 2

在finally执行完了之后x的值已经变成2了,按照你说的那样主函数接受的返回值应该是2猜对啊,
回复 使用道具 举报
执行到return的时候,x的值是1,此时内存中会有一个路径产生,该路径的返回值时1,但是return下面还有一个finally代码块,所以先执行finally代码块,代码块执行完后再返回以前的执行路径,将x=1返回。
回复 使用道具 举报
结果是这个 有什么问题吗?
try: x = 1
finally: x = 2
main: 1
那个return 是整个方法执行完了才把值返回去的,并不是执行到try 的时候就马上返回去的。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马