例子说明问题。
//代码一
public class Test1 {
StringBuffer a = new StringBuffer("a");
StringBuffer b = new StringBuffer("b");
public static void main(String[] args) {
Test1 t = new Test1();
t.test(t.a,t.b);
System.out.println(t.a);
System.out.println(t.b);
}
public void test(StringBuffer a, StringBuffer b) {
a.append("L");
b.append("L");
}
}
程序输出:
aL
bL
//代码二
public class Test1 {
StringBuffer a = new StringBuffer("a");
StringBuffer b = new StringBuffer("b");
public static void main(String[] args) {
Test1 t = new Test1();
t.test(t.a,t.b);
System.out.println(t.a);
System.out.println(t.b);
}
public void test(StringBuffer a, StringBuffer b) {
a = new StringBuffer("aL");
b = new StringBuffer("bL");
}
}
程序输出:
a
b
一开始我对第二个程序的结果百思不解。为什么在程序一里面,在test里面对a进行操作,main方法里面的t.a改变了,而在程序二里面操作,在main中却没有改变其值。 做了些测试左后,有点理解了。我就把自己理解的表达一下吧。
为了表达两个引用的不同,用t.a 和 a 对应起来 t.a代表实参,a代表形参。
在引用传递中 t.test(t.a,t.b);这句话,t.a 把他的引用地址传给了 StringBuffer a 这里的a , t.b 把他的引用地址传给了 StringBuffer b 这里的b 。
上一个丑丑的内存图。(不能上传图。。。。。白画了。。。。。T_T。。。。写字吧)
当a 复制到了 t.a 的引用后,他们当然都指向了同一块内存。这时候的状态就是,这2个引用指向同一块内存地址。
这2个引用都可以对内存进行操作,这就解释了程序一中的内存中的值的改变。(在test方法中做了a.append("L"),使内存中的值变成了aL)
而在程序二中,对a new 了一个新的对象,这时在内存中行为是,现在的a指向了另外一块内存,该内存的值为:aL。为t.a这个引用依然指在原来的内存,值为:a。所以结果就是那样了。
个人表达能力有限,其实画个图最容易解释了。可以不能上传,坑爹?