黑马程序员技术交流社区

标题: 我的基础测试中的一道题。。。晕 [打印本页]

作者: zhou5852    时间: 2013-7-12 22:50
标题: 我的基础测试中的一道题。。。晕
8、 写一个类证明return是在finally执行后才返回的,且在finally无法改变返回值。( 完整拷贝  无一点更改痕迹)
我的代码如下   我最后竟然证明了 finally 可以改变返回值。。。。是不是证明题库的题有问题   你们怎么看。。。。。
  1. public class _8_Question {
  2.         public static void main(String[] args){
  3.                
  4.                 System.out.println(finallyTest());
  5.         }
  6.         @SuppressWarnings("finally")
  7.         public static String finallyTest() {
  8.                 String str = null;
  9.                 try {
  10.                 return        str = "已经执行到try中的语句了";
  11.                 } catch (Exception e) {
  12.                         // TODO: handle exception
  13.                 }
  14.                 finally{
  15.                         System.out.println("finally 块中的方法被执行了");
  16.                         return "finally中的return语句被执行了";
  17.                 }
  18.                
  19.                
  20.                
  21.         }

  22. }
复制代码

作者: ㄗs:/|丶hearts    时间: 2013-7-12 22:53
你吧finnaly语句中的return语句去掉
作者: zhou5852    时间: 2013-7-12 22:55
我再贴个运行后的的吧。。。。。
finally 块中的方法被执行了
finally中的return语句被执行了
作者: ㄗs:/|丶hearts    时间: 2013-7-12 23:08
zhou5852 发表于 2013-7-12 22:55
我再贴个运行后的的吧。。。。。
finally 块中的方法被执行了
finally中的return语句被执行了 ...

你的finally语句中有return语句,执行finally语句就必然执行了里面的return语句,返回了值。  这样怎么能证明问题呢?!
把我当时做的给你看看吧
  1. public class Test7 {

  2.         /**
  3.          * 7、 写一个类证明return是在finally执行后才返回的,且在finally无法改变返回值。
  4.          * @param args
  5.          */
  6.         public static void main(String[] args) {
  7.                 // TODO Auto-generated method stub

  8.                
  9.                 //该句打印的str是 “finally之前的str”  finally没有改变返回值
  10.                 System.out.println(ReturnStr());
  11.         }

  12.        

  13.         public static String ReturnStr(){
  14.                 String str;
  15.                 try{
  16.                         str="finally之前的str";
  17.                         System.out.println("没有执行finally前--"+str);
  18.                         return str;
  19.                        
  20.                 }finally{
  21.                         str="finally之后的str";
  22.                         //如果打印了这句,证明finally语句执行了  也就是return在finally执行后才返回的
  23.                         System.out.println("--执行了finally后--"+str);
  24.                 }                       
  25.         }
  26. }
复制代码

作者: 肥猫    时间: 2013-7-13 00:34
       首先,因为JAVA的GC机制不允许你的TRY和FINALLY中都有RETURN的。因为RETURN在TRY中若是一运行将导致CATCH和FINALLY的代码都作废,这样将导致很多资源关闭不了JVM负担过大,容易造成内存溢出。所以系统若是在FINALLY中找到RETURN会自动过滤掉TRY中的的RETURN,所以你在FINALLY中定义返回就就是你的致命伤了。
作者: zhou5852    时间: 2013-7-13 08:45
我现在 分析一下题目  题目说写一个类证明return是在finally执行后才返回的,且在finally无法改变返回值。
这是两部分,我们很容易证明前半句,  在题目中说   finally 无法改变返回值????而我在finally 中的return 已经明显将返回值改变了  我想说这个题目是错的。。。。你们认为呢。。。
作者: ㄗs:/|丶hearts    时间: 2013-7-13 11:25
本帖最后由 ㄗs:/|丶hearts 于 2013-7-13 11:29 编辑
zhou5852 发表于 2013-7-13 08:45
我现在 分析一下题目  题目说写一个类证明return是在finally执行后才返回的,且在finally无法改变返回值。  ...


我想说 你的思路是错的。  finally中有return语句,没法证明finally可以改变返回值。不管前面有多少return,返回的是什么, finally中的return都会执行并返回一个值,你写的是return "finally中的return语句被执行了";直接就返回return后的字符串了,不存在改变return中的返回值。  你把他改为 str= "finally中的return语句被执行了";

作者: zhou5852    时间: 2013-7-13 12:47
ㄗs:/|丶hearts 发表于 2013-7-13 11:25
我想说 你的思路是错的。  finally中有return语句,没法证明finally可以改变返回值。不管前面有多少retur ...

额。。。题目说 return 无法改变返回值,意思是说我在finally 里 就改变不了 这个函数以前的返回值了,而事实证明  在finally 能改变返回值啊     按照你的改该法。。改为 str= "finally中的return语句被执行了";  就是说str 其实在这段程序中 指向了 两个变量,而return返回的是 离它最近的变量的地址,而不是finally 后指向的地址,这样就能证明 后一句  在 finally 无法改变返回值了?:L。。。。。。。
作者: zhou5852    时间: 2013-7-13 12:51
我仔细看后  这道题 前一问  还大有问题  看如下代码和执行
  1. public class _8_Question {
  2.         public static void main(String[] args){
  3.                
  4.                 System.out.println(finallyTest());
  5.         }
  6.         public static String finallyTest(){
  7.                 String str = null;
  8.                 try {
  9.                        
  10.                   return fun();
  11.                 }
  12.                 finally{
  13.                         System.out.println("finally 块中的方法被执行了");
  14. //                        return "finally中的return语句被执行了";
  15.                 }
  16.                 }
  17.                
  18.          public static String fun(){
  19.                  System.out.println("Try 中return中的方法");
  20.                 return  "123";
  21.          }
  22.                
  23.                
  24.                

  25. }
  26. /*运行结果*/
  27. //Try 中return中的方法
  28. //finally 块中的方法被执行了
  29. //123
复制代码

作者: ㄗs:/|丶hearts    时间: 2013-7-13 13:05
zhou5852 发表于 2013-7-13 12:47
额。。。题目说 return 无法改变返回值,意思是说我在finally 里 就改变不了 这个函数以前的返回值了,而 ...

你为啥老这样写呢?  return  "123";
前面写return  str; 然后在finally中改变str的值 来证明finally是否改变了return的返回值。
要像你那样写的话,不管前面有多少return,肯定返回的是最后一个return。
例如:return  "123";return  "34";return  "2222";return  "7";    最后返回的肯定是7呀
作者: zhou5852    时间: 2013-7-13 13:16
ㄗs:/|丶hearts 发表于 2013-7-13 13:05
你为啥老这样写呢?  return  "123";
前面写return  str; 然后在finally中改变str的值 来证明finally是 ...

我明白你的意思   你的意思就是 引用类型如果在return 的时候 它引用的是一个地址值,若在后续的finally 改变它的地址值,整个函数返回的是 return的地址值而不是 在finally 改变的 引用地址值 。。。主要是这个题目可以有多重理解方式,各种理解方式都有理。。。。
作者: ㄗs:/|丶hearts    时间: 2013-7-13 13:31
zhou5852 发表于 2013-7-13 13:16
我明白你的意思   你的意思就是 引用类型如果在return 的时候 它引用的是一个地址值,若在后续的finally  ...

我觉得吧 你那样写就不叫改变返回值了。 你是两个地方都有return语句呀
作者: ㄗs:/|丶hearts    时间: 2013-7-13 18:27
ㄗs:/|丶hearts 发表于 2013-7-13 13:31
我觉得吧 你那样写就不叫改变返回值了。 你是两个地方都有return语句呀

证明了 finally 中可以返回值  但没有证明finally中可不可以以改变返回值 。。。 所以不合题意。。
作者: longlangcx    时间: 2013-7-14 10:41
不要钻牛角尖儿,知道人家想问你的是什么就行了。

我也觉得这题严格来讲不是很严谨。严格意义的“finally无法改变返回值”,应该是前面的try块一但写好了并有了一个返回值,则finally块无论写什么返回值都无法改变,而事实上LZ确实通过finally中的return语句改变了函数的返回值。题目应该就是在扣“改变”这个字眼儿吧,finally里的return是重新设定了一个返回值,而不是改变了之前的返回值。比如try块中return i; finally块中来个i++,无法改变之前返回的i的值,题目貌似是这意思,所以LZ就顺着题意走吧~~

其实关于这题,我纠结的不是后半句,而是前半句,感觉前半句才是难以证明的。怎么证明它是先返回了一个值、然后再执行的finally语句,还是先执行了finally语句、再返回的值呢?值的返回是没有现象的,我们只是知道finally最终会被执行到罢了。
作者: zhou5852    时间: 2013-7-14 11:00
longlangcx 发表于 2013-7-14 10:41
不要钻牛角尖儿,知道人家想问你的是什么就行了。

我也觉得这题严格来讲不是很严谨。严格意义的“finally ...

额   的确你的想法很好  我试试基本数据类型 而不是引用类型 行不行。。。。
作者: longlangcx    时间: 2013-7-14 19:18
9楼的代码我看了,跟我的解法差不多,我也是在try块中弄了一个return,return一个返回int型成员变量的方法,然后再在finally中试图去改变这个int值,感觉靠谱儿,跟出题人的思路应该差不多。

至于严谨不严谨的问题,我感觉这题目本身就不严谨,两部分都无法证明。后半部分可通过finally中的return覆盖try中的return的现象,某种意义上讲也是在改变返回值,因此能证明题目是错的。而前半部分,根本无从证明。较真的话,就说可能是先返回了一个值,然后再执行finally语句,当finally语句中有return时,覆盖之前的返回值。这样的话等于返回了两次值,那么前面不就先返回了一次么?虽然从表达式替代上来说,应该是直接替代为一个字面值,这样应该不存在两次返回,但是如何证明呢?

题目暂且不管,就说这个的实际流程。我感觉是这样:
首先执行到try中的return语句时,先确定需要return的值,然后再去执行finally,如果finally中没有return语句,则在finally执行结束后,返回之前已经确定的值,如果finally中有return语句,则返回finally中return的值。

我就把这流程给写题目上了,证明不证明的,照着出题人的思路说说就行了~
作者: zhou5852    时间: 2013-7-15 10:53
longlangcx 发表于 2013-7-14 19:18
9楼的代码我看了,跟我的解法差不多,我也是在try块中弄了一个return,return一个返回int型成员变量的方法 ...

恩  咱们理解是一样的:lol
作者: yuhui    时间: 2013-7-23 11:44
加油加油加油




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