黑马程序员技术交流社区

标题: 怎么利用StringBuffer使插入finally执行的结果是一样的值 [打印本页]

作者: 深井看海    时间: 2012-11-25 21:47
标题: 怎么利用StringBuffer使插入finally执行的结果是一样的值
本帖最后由 深井看海 于 2012-11-29 23:56 编辑

怎么利用StringBuffer将下面的程序修改后,使插入finally执行的结果是一样的值???
class Test1{
public static void main(String[] args){
  System.out.println(fun());
  }
  
public static int fun(){
  int i = 1;
  try {
   i++;
   if(true){
    return i;
   }
  }catch(Exception e){
   i++;
   if(true){
    return i;
   }
  }finally{
   //当finally插入执行时,它就好像是一个调用的方法一样
   //当finally中使用的所有变量,都是copy过来的
   //在finally中使用了几个变量,那么就相当于finally这个方法中有几个形参,这都需要实参copy
   i++;
   System.out.println("finally:" + i);
   }
   return i;
  }
}
作者: yzqiong5566    时间: 2012-11-25 22:18
对你上面的问题有些困惑。如果仅仅是想finally的输出结果和方法返回的结果一致的话。下面就可以:
方法1:
  1. public static int fun() {
  2.                 StringBuffer sb = new StringBuffer();
  3.                 int i = 1;
  4.                 try {
  5.                         i++;
  6.                         if (true) {
  7.                                 sb.append(i);
  8.                                 return i;
  9.                         }
  10.                 } catch (Exception e) {
  11.                         i++;
  12.                         if (true) {
  13.                                 sb.append(i);
  14.                                 return i;
  15.                         }
  16.                 } finally {
  17.                         i++;
  18.                         System.out.println("finally:" + sb.toString());
  19.                 }
  20.                 return i;
  21.         }
复制代码
或者是:
public static int fun() {
                StringBuffer sb = new StringBuffer();
                int i = 1;
                try {
                        i++;
                        if (true) {
                                sb.append(i);
                                return i;
                        }
                } catch (Exception e) {
                        i++;
                        if (true) {
                                sb.append(i);
                                return i;
                        }
                } finally {
                        i++;
                        i = Integer.parseInt(sb.toString());
                        System.out.println("finally:" +i);
                }
                return i;
        }

还有很多种方式。希望是你想要的。
作者: 王震阳老师    时间: 2012-11-25 22:30
yzqiong5566 发表于 2012-11-25 22:18
对你上面的问题有些困惑。如果仅仅是想finally的输出结果和方法返回的结果一致的话。下面就可以:
方法1: ...

我感觉楼主的意思是,在finall{}里是i++,实现,本来i=2;在finally里是i=3;是return的值和finally{}里打印的值一样(3)。但是你的回答,相当于在定义一个StringBuffer对象,该对象i的值,然后再打印该对象里的值。并没有起到实际效果呀。那和定义一个 int k;k=i;然后都打印k有啥区别呢?
作者: yzqiong5566    时间: 2012-11-25 22:37
王震阳 发表于 2012-11-25 22:30
我感觉楼主的意思是,在finall{}里是i++,实现,本来i=2;在finally里是i=3;是return的值和finally{}里 ...

是这样的。如果想i++之后打印结果一致有很多方法,他要求要用StringBuffer就是有点让人困惑的地方。
比如方法2,是在i++只有打印的结果和方法return的结果是一致。 而且也可以在方法return i;之前先i--,更本就不用StringBuffer类,就可以一致。如下代码:
  1.         public static int fun() {
  2.                 int i = 1;
  3.                 try {
  4.                         i++;
  5.                         if (true) {
  6.                                 return i--;
  7.                         }
  8.                 } catch (Exception e) {
  9.                         i++;
  10.                         if (true) {
  11.                                 return i--;
  12.                         }
  13.                 } finally {
  14.                         i++;
  15.                         System.out.println("finally:" +i);
  16.                 }
  17.                 return i;
  18.         }
复制代码

作者: 王震阳老师    时间: 2012-11-25 22:51
yzqiong5566 发表于 2012-11-25 22:37
是这样的。如果想i++之后打印结果一致有很多方法,他要求要用StringBuffer就是有点让人困惑的地方。
比如 ...

是的,这段代码也可以让两者打印一致,但是我的饿疑问是,本质的问题是finally能否改变变量i的值(这个是可以的,首先可以肯定)并且让这个值返回到上面函数的return中去影响它。这个可不可以我真还不知道,并不只是让他们打印的值一样,毕竟打印出来的值一样,都是“表面现象”,在内存中,jvm到底是怎样处理的,这是我最想问的.感谢你的回复。
作者: yzqiong5566    时间: 2012-11-25 23:06
王震阳 发表于 2012-11-25 22:51
是的,这段代码也可以让两者打印一致,但是我的饿疑问是,本质的问题是finally能否改变变量i的值(这个是 ...

那我就回答你现在的问题。
其一,finally是可以改变变量的值的(因为finally块的代码是在return之前执行的,更准确的应该是在中间执行)。
其二,该例子中,finally无法直接影响return的结果,为什么呢?执行的逻辑是这样的:当函数执行到return语句的时候,发现还有finally块要执行,这个时候他会把return的结果单独放在一个空间暂存(一个确定了的值),当finally执行完成后,虽然i++了,但是暂存的那个值不是i本身,所以return的结果是2,但是finally里打印的结果是3就是如此。
其三,如果返回的是对象的引用,可以通过改变引用的指向来改变return的结果的。
作者: yzqiong5566    时间: 2012-11-25 23:19
本帖最后由 yzqiong5566 于 2012-11-25 23:20 编辑
yzqiong5566 发表于 2012-11-25 23:06
那我就回答你现在的问题。
其一,finally是可以改变变量的值的(因为finally块的代码是在return之前执行的 ...


代码:
  1. package www.itcast.com;

  2. public class Demo3 {
  3.         public static void main(String[] args) {
  4.                 System.out.println(TestItcast.testBasicType());
  5.                 System.out.println(TestItcast.testReferenceType());
  6.         }
  7. }

  8. class TestItcast {//工具类
  9.         static int testBasicType() {//测试基本数据类型
  10.                 int x = 1;
  11.                 try {
  12.                         return x;
  13.                 } finally {
  14.                         ++x;
  15.                 }
  16.         }
  17.         static Student testReferenceType() {//测试引用数据类型
  18.                 Student stu = new Student("Tom");
  19.                 try {
  20.                         return stu;
  21.                 } finally {
  22.                         stu.setName("Nina");
  23.                 }
  24.         }
  25. }

  26. class Student {//学生类
  27.         private String name;

  28.         public Student(String name) {
  29.                 super();
  30.                 this.name = name;
  31.         }

  32.         public void setName(String name) {
  33.                 this.name = name;
  34.         }

  35.         public String toString() {
  36.                 return "姓名是:" + this.name;
  37.         }
  38. }

  39. /**
  40. * 執行結果是:
  41. * 1
  42. * 姓名是:Nina
  43. */
复制代码

作者: 深井看海    时间: 2012-11-29 23:39
都好强大,受教了{:soso_e130:}




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