[code="java"]
public class Test {
public static void main(String[] args){
StringBuffer a = new StringBuffer("adc");
StringBuffer b = new StringBuffer("efg");
Test test = new Test();
test.change(a, b);
System.out.println(a);
System.out.println(b);
}
public void change(StringBuffer a ,StringBuffer b){
a.append(b);
b = a;
}
}
[/code]
[code="java"]
System.out.println(a);
System.out.println(b);
[/code]
上面的输出结果为什么是:abcefg和efg 而不是 abcefg 和 abcefg?
图片没有发好:
[img]http://dl.iteye.com/upload/attachment/0061/8739/963f057a-ebfe-35a1-84db-673b03c746cb.jpg[/img]
又是局部变量作用域的问题
[code="java"]
public static void main(String[] args){
StringBuffer a = new StringBuffer("adc");
StringBuffer b = new StringBuffer("efg");
Test test = new Test();
test.change(a, b);
System.out.println(a);
System.out.println(b);
}
public void change(StringBuffer t1 ,StringBuffer t2){
t1.append(t2);
t2 = t1; //与外面的 StringBuffer b 不是同一个对象引用
}
[/code]
这样就能得到你想要的结果,对比一下
[code="java"]
//全局
static StringBuffer b = new StringBuffer("efg");
public static void main(String[] args){
StringBuffer a = new StringBuffer("adc");
Test test = new Test();
test.change(a);
System.out.println(a);
System.out.println(b);
}
public void change(StringBuffer a ){
a.append(b);
b = a;
}
[/code]
[code="java"]public void change(StringBuffer a ,StringBuffer b){
a.append(b);
b = a;
}[/code]
这段代码中,StringBuffer的append方法会把直接修改先前的StringBuffer变量,也就是说以前的StringBuffer变量 a - {"abd"} 已经不存在了,你永远也找不到了,不管是在堆内存还是栈内存,那么就解释了a.append(b)直接改变了a的堆内存的数据,以后你再想使用a变量,得到的只能是修改后的值。
StringBuffer变量b,采用了=,=意味着地址引用的改变,b=a只是改变了当前局部函数内部,b的地址引用,而 *b - {"efg"}在堆内存中都含有数据,还没有被销毁或改变。当前局部函数做的只是传值调用,等函数结束后,一切都是没有改变的,如果想要改变b的值,那么可以使用return语句,把b的值传回来,然后在主函数(main也是一个函数,也有变量作用域的)中,这样,再把函数的返回值赋给b,就可以了。
[code="java"]
public void change(StringBuffer a ,StringBuffer b){
a.append(b); //这个是向 字符串a缓冲区“追加”元素b这样改变了a的缓存区的值,即改变了a
b = a; a,//这个只是值传递,和赋值操作,并不会改变变量a,b
}
[/code]
[code="java"]
public class Test {
public static void main(String[] args){
StringBuffer a = new StringBuffer("adc");
System.out.println(b.hashCode()); //1
StringBuffer b = new StringBuffer("efg");
Test test = new Test();
test.change(a, b);
System.out.println(b.hashCode()); //2
System.out.println(a);
System.out.println(b);
}
/**
当调用方法change(a,b)时
因为append方法是再字符串原有对象地址存储上,进行连续操作
实际上操作的时a变量。
sb=sa;这个sb与b的内存地址根本不是同一个
这个时候的sb指向不同的地址、
**/
public void change(StringBuffer sa ,StringBuffer sb){
sa.append(sb);
sb = sa;
System.out.println("我其实不是类的成员变量b我是我自己的b"+sb ); //这个时候打印的应该是a被修改后的值
System.out.println(b.hashCode()); //3
}
}
你可以发现1,2,3处的hashcode
1,2处相同的 表示同一个b
第3处的hashcode与1,2不同 因为他们根本 不是同一个b
[/code]
楼上大家说了很多,这其实是一个java中的实参和形参的问题。
为了便于理解我图解一下:
[img]
http://dl.iteye.com/upload/attachment/0061/8739/963f057a-ebfe-35a1-84db-673b03c746cb.jpg
[/img]
1.当 执行a.append(b); 改变了实参对应实例的值。没有改变实参的引用。
2.当执行 b = a; 时,实际上将形参b指向了实参a所对应的实例。并没有改变实参
a的引用。所以打印出来的是"efg"而不是"abcefg".
3.将代码做如下改动:
[code="java"]
public void change(StringBuffer a ){
a.append(b);
b = a;
System.out.println("我是形参b现在对应实例的值:"+b);
}
[/code]
会输出:我是形参b现在对应实例的值:abcefg.