首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

有关StringBuffer的有关问题

2013-06-25 
有关StringBuffer的问题public class Test {public int inc() {int xtry {x 1return x} catch (Excep

有关StringBuffer的问题
public class Test {
     
    public int inc() {
        int x;
        try {
            x = 1;
            return x;
        } catch (Exception e) {
            x = 2;
            return x;
        } finally {
            x = 3;
        }
    }
     
    public StringBuffer inc(StringBuffer x) {
        try {
            x.append("1");
            x = new StringBuffer();// 如果在里面加参数例如这样new StringBuffer("5")结果就变了
            return x;
        } catch (Exception e) {
            x.append("2");
            return x;
        } finally {
            x.append("3");
            x = new StringBuffer("4");
              //这后面加return x;也会变
        }
    }
     
    public static void main(String[] args) {
        int x = new Test().inc();
        System.out.println(x);
        StringBuffer x1 = new StringBuffer(),x2 = new Test().inc(x1);
        System.out.println(x1);
        System.out.println(x2);
    }
}

问:new StringBuffer();是否是重新开辟了一块内存,在这单中x1,和x2的指向是否有变化? stringbuffer
[解决办法]
1、StringBuffer 第一次new 都会生成新的引用。因为x是形参变量,所以不会对原有地址里面的数据发生更改。
2、finally 关键字是在运行try里面的return 语句后才会被执行的,其实x = new StringBuffer("4");  x的值已经被更改了,但是因为try里面的return已经把值返回给主调程序,所以就算更改了也无法返回数值。
[解决办法]
执行x2 = new Test().inc(x1);这句话时,对传入的x1进行了 x.append("1");操作x1该内存地址的对象值变为1;

之后,变量x指向发生变化,指向新地址,并将新地址对象进行返回:


x = new StringBuffer();
return x;

对于新对象,在finally里进行了 x.append("3");的操作,使inc(x1)返回的是3的对象,之后变量x又指向新地址,这个地址没什么用了

这个东西一看还真比较晕乎,debug一下思路会清晰一些的。
[解决办法]
首先弄清楚两个问题:
1、call by reference
2、finally执行的时机

首先,在java中,call by reference只是传入reference 变量的值赋予子函数的局部变量,并不是真的把引用变量传进去。结合这次具体的例子,则为变量x1指向的地址,赋给子函数中的局部变量x。这样,x1与x指向同一个对象,当修改对象的内容时,如x.append("1"),会影响x1,因为x1指向的对象的内容发生了变化。但是,当局部变量x的值被修改,指向其他对象时,如x = new StringBuffer(),并不会影响x1。

其次来看finally执行的时机。一般我们认为finally在renturn之前执行,但实际上在执行到return子句时,子函数会先将返回值放到主函数的“接收空间”中,再去执行finally中的内容。这样一来如果在finally中不重新return,是不会改变子函数的返回值的。在本例中,finally中有两次操作:一次修改了局部变量x指向的对象的内容x.append("3");一次修改了局部变量x的值,指向新的对象x = new StringBuffer("4")。因为函数返回值是x之前指向的对象,是在finally中的内容执行前就确定的,所以后一次操作(x = new StringBuffer("4"))对子函数的返回值是没有影响的。

下面是执行过程的细节,如果上面的描述不够清晰,不好理解。可以先看一下下面的详细流程。

StringBuffer x1 = new StringBuffer()
有关StringBuffer的有关问题

x2 = new Test().inc(x1)

... StringBuffer inc(StringBuffer x) 子函数开始执行...
有关StringBuffer的有关问题

...x.append("1")
有关StringBuffer的有关问题

...x = new StringBuffer()
这里局部变量x指向的地址发生了变化,但x1并不会随之变化。
有关StringBuffer的有关问题

... return x
这时子函数会把返回值放入主函数用于接收的“空间中”,然后去执行finally中的内容,finally中的内容执行完成后才会结束子函数。
有关StringBuffer的有关问题

接着执行finally中的内容:
... x.append("3")
有关StringBuffer的有关问题

...x = new StringBuffer("4")
注意这里并没有改变子函数的返回值,仅仅是局部变量X指向的地址发生了变化。
理解这里后,可以明白这里对后来x2的赋值没有影响。
(如果你在finally中最后在return x一次,子函数的返回值会改变,后来x2赋值时,会指向和局部变量x相同的地址。)
有关StringBuffer的有关问题

...子函数执行结束,回到x2 = new Test().inc(x1)
有关StringBuffer的有关问题

接下来就会打印出结果。所以会出现“1”“3”。

热点排行