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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 朴日男 中级黑马   /  2014-10-4 08:57  /  1900 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 朴日男 于 2014-10-4 09:15 编辑

/*
* 6、 用代码证明,在try中写了return,后面又写了finally,是先执行return还是先执行fianlly?
*
* */
/*
* 输出结果:
try run
finally run
x=2
*   
* 从test()结果看出,返回值是x=2;
* 因此执行顺序是:
* return拿到返回值(x=2)不返回先等待(x在内存里的什么地方呢???)
* -->执行finally的内容(x=5)(x在内存里的什么地方呢???)
* --> try里的return继续执行(x=2)(x存在哪里了?为什么没有被覆盖?)
*  
* 总结:
* finally先执行,return后执行.
* 如果这么说,打印结果应该是 x=5啊
*
* return先执行,finally后执行.
* 如果这么说,那执行结果应该是
* try run
* x=2
* finally run
*
* 求助啊...最好从内存 方面解析讲解,跪谢...百度了下,也没看出所以然来,都是各说各的...2种结果都有
* 更迷糊了.
* */
class Test6
{
      public static void main(String[] args)
      {
            System.out.println("x = "+test());
      }
      public static int test()
      {
            int x = 1;
            try
            {
                  System.out.println("try run");
                  x++;
                  return x;
            } finally
            {
                  x = 5;
                  System.out.println("finally run");
            }
      }
}

评分

参与人数 1技术分 +1 收起 理由
敏敏好学 + 1

查看全部评分

10 个回复

倒序浏览
先是return 然后才是finally,
回复 使用道具 举报
额 return在函数执行完在返回结果?
回复 使用道具 举报
两种情况:
1.如果finally中没有return,先执行的是try catch中的return,再执行finally
2.如果finally中还有return,返回的是finally中的return

对于第一种情况:
如果操作的是基本数据类型,返回值不受影响
如果操作的是引用数据类型,返回值会受影响

  1. class TryFinallyTest
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 int result = test1();
  6.                 System.out.println(result);//返回的是2

  7.                 String str = test2().toString();
  8.                 System.out.println(str);//返回的是25
  9.         }

  10.         //基本数据类型,finally操作不会影响返回值
  11.         public static int test1()
  12.         {
  13.                 int x = 0;
  14.                 try
  15.                 {
  16.                         x = 2;
  17.                         return x;
  18.                 }
  19.                 finally
  20.                 {
  21.                         x = 5;
  22.                 }
  23.         }

  24.         //引用数据类型,finally操作会影响返回值
  25.         public static StringBuilder test2()
  26.         {
  27.                 StringBuilder sb = new StringBuilder();
  28.                 try
  29.                 {
  30.                         sb.append(2);
  31.                         return sb;
  32.                 }
  33.                 finally
  34.                 {
  35.                         sb.append(5);
  36.                 }
  37.         }
  38. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
敏敏好学 + 1 赞一个!

查看全部评分

回复 使用道具 举报 1 0
WakeUp 发表于 2014-10-4 12:00
两种情况:
1.如果finally中没有return,先执行的是try catch中的return,再执行finally
2.如果finally中还 ...

说的有道理,正解
回复 使用道具 举报
我的理解:
对于有返回值的方法,执行到return语句的时候会把返回值压入调用栈中(注意是值,对于基本数据类型就相当于拷贝一份,对于引用数据类型就相当于将地址拷贝一份),而后检查是否有finally语句块,如果有的话则执行,对于一楼的例子而言finally要进行的有赋值和输出操作,输出不管,赋值的话应该是成功赋值的,但是将5赋给变量x之后并未重新return,所以调用者接收到的还依旧是之前return时候的值。
为了验证这点,可以把finally里面那句打印“finally run”的语句变为输出x的值、或者再次进行return,想必能看到一些端倪的。
对于引用类型而言就更简单了,它里面存放的是地址值,finally里没有return的话的确不能改变这个地址,但是可以改变里面对象的内容,因为始终只有一个对象,所以调用者拿到的肯定是已经被改变过的。
如果上面无法理解的话,可以这样想:
return 表达式;
上面这句return语句可以看成总共做了两件事,第一件是计算表达式的值,并将其存储起来,第二件是为方法的返回做准备,如果finally中不存在return语句,则可以看成这样:
1、变量 ?=表达式;
2、return ?;
而若是有finally语句块的话,实际上是在上面两句话之间执行的,它可以改变表达式的值,但若不重新return的话是无法改变?的值的。
回复 使用道具 举报
finally中用return不是个好习惯,他会覆盖前面所有的return和吃掉catch中抛出的异常
回复 使用道具 举报
水竹 中级黑马 2014-10-4 16:46:43
8#
犹豫铅笔 发表于 2014-10-4 16:19
finally中用return不是个好习惯,他会覆盖前面所有的return和吃掉catch中抛出的异常 ...

嗯,我只是为了说的严谨一点,并没有赞成这种做法。
回复 使用道具 举报
WakeUp 发表于 2014-10-4 12:00
两种情况:
1.如果finally中没有return,先执行的是try catch中的return,再执行finally
2.如果finally中还 ...

膜拜!!!...:handshake...豁然开朗
回复 使用道具 举报
水竹 发表于 2014-10-4 15:20
我的理解:
对于有返回值的方法,执行到return语句的时候会把返回值压入调用栈中(注意是值,对于基本数据 ...

对于有返回值的方法,执行到return语句的时候会把返回值压入调用栈中(注意是值,对于基本数据类型就相当于拷贝一份,对于引用数据类型就相当于将地址拷贝一份)
这句话我收藏...呵呵, 谢谢 :)
回复 使用道具 举报
朴日男 发表于 2014-10-4 16:54
对于有返回值的方法,执行到return语句的时候会把返回值压入调用栈中(注意是值,对于基本数据类型就相当 ...

嗯,不过前面也说过了,这只是我的理解,至于java虚拟机内部怎么实现的我也不敢保证,所以这句话并不一定对。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马