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

本帖最后由 王清华0 于 2013-8-8 22:27 编辑

黑马测试题中的第八题:写一个类证明return是在finally执行后才返回的,且在finally无法改变返回值。在《java核心技术》中给的解释是:
return在try中,则保留返回值,执行完finally之后才返回,并且finally中无法改变返回值。
return在finally中,则在执行finally的过程中,优先执行这个返回,覆盖掉try中的返回值。
return在try{}finally{}之外的话 ,finally改变的值会作为return的返回值。
那么按照这个说法,我们的测试题明显是针对第一种情况问的了,我答题的代码如下:
  1. public class Test8 {
  2.         public static void main(String args[]){
  3.                 int var = 4;
  4.                 System.out.println("第一次调用,证明finally无法改变return的值,var此时的值为:"+method_1(var));
  5.                 System.out.println("第二次调用,证明try中的return晚于finally,var此时的值为:"+method_2(var));

  6.         }
  7.         //第一个函数,在try中返回var的值,在finally中改变var的值,输出结果为改变finally改变之前的,证明finally无法
  8.         //改变返回值
  9.         public static int method_1(int var){
  10.                 try{
  11.                         var = 5;
  12.                         return var;
  13.                 }
  14.                 finally{
  15.                         var=6;
  16.                         }
  17.         }

  18.         //第二个函数,在try和 finally中都返回var的值,根据java的原则,遇到第一个return即返回,不再执行接下来的return语句。
  19.         //如果返回值为5,则优先执行try中的return,如果返回值为6,则优先执行了finally中的return。
  20.         @SuppressWarnings("finally")
  21.         public static int method_2(int var){
  22.                 try{
  23.                         var = 5;
  24.                         return var;
  25.                 }finally{
  26.                         var = 6;
  27.                         return var;
  28.                 }
  29.         }
  30. }
复制代码
结果也是按照我注释的结果体现的,证明了题目要求。
但是我总是觉得这种证明方式有取巧的嫌疑,我觉得能不能用线程sleep的形式直观的表现出来其执行顺序,但是我写了多次都没有写出正确的程序,求助。

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1

查看全部评分

18 个回复

倒序浏览

不对吧,这也是我最初想到的方法,但是这样子只能证明finally无法改变返回值而已,不能证明其先后顺序。
因为打印“finally执行”的这一句是在被调用函数boov()里面执行的,而打印“return返回给boov”则是已经在main()函数中了。原本就应该是这个执行顺序啊。感觉还不如我的证明方式有说服力呢。
因为我们 都想到用return的返回值输出结果晚于finally之后,来证明其执行顺序问题,但是问题就在于,return只能是返回值,而输出这个返回值已经是原函数的执行问题了,等于是偷换了问题的题目。因此核心问题就是return只是单纯的返回值,而我们无法在控制台中明确的知道这个返回的执行时间。
因此我才觉得用线程sleep的方式更加好,让finally的执行 延迟3到5秒,这绝对已经超出了return的执行时间,或者是,有一个类似于监听器 的东西,可以监听return这个事件。这样子才更加直白有说服力一些。但是仍然谢谢了。
回复 使用道具 举报
oath 发表于 2013-8-8 18:31
疏忽了 ,,呵呵   你看下面的,,可不可以证明finally是先执行的

这个方式貌似可以,单纯的以main函数的结束来证明finally优于return,但是还是感觉有取巧的嫌疑,我是求线程sleep方式或者监听器的方式,这样 证明更加直观。
回复 使用道具 举报
oath 发表于 2013-8-8 19:22
其实  在finally中无法改变返回值 ,就已经说明了finally是先执行的,,,

啊?这个逻辑有点不对啊,为啥他没有改变就证明 先执行呢?这个完全相反吧 。
回复 使用道具 举报
oath 发表于 2013-8-8 20:02
呵呵 是啊,,你的证法,先不管对错,,涉及到的知识肯定是更多的

但  你看啊,他出这个题 要证明两个问 ...

我和你看法不一样
首先是try中的return的值以及finally的改变,我认为是return保存返回值 ,finally执行完了之后才执行返回,而不是finally中改一遍 return再改一遍。
再一个是关于这个题目,我觉得这两问不能归为一个,我还是觉得按照你的方式逻辑无法证明。
回复 使用道具 举报
  1. package day01;

  2. public class test7
  3. {        
  4.         public static String boov(String str)
  5.         {        
  6.                 try
  7.                 {                        
  8.                         str="“return返回给boov”";
  9.                         return demo.demo_1();               
  10.                 }
  11.                 finally
  12.                 {        
  13.                         System.out.println("finally执行");
  14.                         return demo.demo_2();
  15.                 }                                
  16.         }        
  17.         public static void main(String[] args)
  18.         {        
  19.                 String Str = null;
  20.                 String newStr=boov(Str);
  21.                 System.out.println(newStr);
  22.         }        
  23. }

  24. class demo{
  25.         public static String demo_1(){
  26.                 System.out.println("Demo1");
  27.                 return "demo1";
  28.         }
  29.         public static String demo_2(){
  30.                 System.out.println("Demo2");
  31.                 return"demo2";
  32.         }
  33. }
复制代码
你试一下这一段代码就知道了
try中的return的确被执行了,你可以想象成这个return被放进了一个临时容器,但是下面还有一个finally需要执行,这个时候boov没有立刻结束,而是等finally中的代码执行完了以后才返回,可是很不巧 finally中又有一个return,这个return也进去了临时容器,把前面的return给覆盖掉了...
其实这道题的考察重点并不在这里..因为没有人蛋疼的在finally里写return,假如你在finally里写了return 那你这段程序前面的那一大段代码就变得毫无意义了..反正它怎么执行,怎么return,最终返回的还是我finally里的return...

不知道这样回答你能不能明白

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1

查看全部评分

回复 使用道具 举报 2 0
白堇翎 发表于 2013-8-8 21:05
你试一下这一段代码就知道了
try中的return的确被执行了,你可以想象成这个return被放进了一个临时容器,但是 ...

哥们,是你不明白吧,请仔细看我原来的代码,你的这个跟我原来的代码根本就是没有区别啊。。。。。。
都是利用finally中的return覆盖掉try中的return借以证明finally先执行,但是这个依赖于java的原有特性,每个函数最多只有一个return,执行完第一个return之后其他的不再执行。
我要的是,不利用这个特性 ,而借助于线程 sleep()或者监听器来实现的方法。
回复 使用道具 举报
oath 发表于 2013-8-8 21:06
我的意思是 return 保存返回值   ,就像return的值被final修饰了一样,finally中的语句可以执行的话,值 ...

大哥,看看我最初贴上去的代码,就是在finally中加入return的啊,但是这个要借助于java最多只有一次return的特性。我要的是不借助这个特性的方法啊。
回复 使用道具 举报
王清华0 发表于 2013-8-8 21:13
哥们,是你不明白吧,请仔细看我原来的代码,你的这个跟我原来的代码根本就是没有区别啊。。。。。。
都 ...

你再仔细看看有没有区别  我新建一个类不是没有原因的 你仔细看看打印顺序就知道哪个return先执行了.
但是执行不代表返回
回复 使用道具 举报 1 0
白堇翎 发表于 2013-8-8 21:43
你再仔细看看有没有区别  我新建一个类不是没有原因的 你仔细看看打印顺序就知道哪个return先执行了.
但 ...

看懂了,我的,我看错了。
回复 使用道具 举报
白堇翎 发表于 2013-8-8 21:05
你试一下这一段代码就知道了
try中的return的确被执行了,你可以想象成这个return被放进了一个临时容器,但是 ...

启发了我finally中代码的作用。。说得好
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马