引用类型方法传参的一点领悟
下午碰到一道笔试题,是非常常见的关于引用类型方法传参的题目。代码如下:
public class Demo4 {
public static void main(String[] args) {
StringBuilder a = new StringBuilder("a");
StringBuilder b = new StringBuilder("b");
operator(a,b);
System.out.println(a);
System.out.println(b);
}
private static void operator(StringBuilder a, StringBuilder b) {
a.append(b);
b = a;
System.out.println(a);
System.out.println(b);
}
}
毫不犹豫的选择了答案。
ab
ab
ab
ab
结果一对答案,傻眼了。
正确答案是:
ab
ab
ab
b
瞬间感觉自己的世界观有点动摇。不应该啊。
你看,一开始,有两个StringBuilder的引用,引用a指向一个内容为’a’的StringBuilder对象,引用b指向一个内容为’b’的StringBuilder对象。至此相安无事。
然后出现了一个 operator的方法,让引用a和引用b去方法里逛一圈。
重点来了,我们都知道引用类型做形参,传的不是对象本身,而是对象在内存中的地址。
我坚持这个思想,然后跟着a和b继续往下走。
在operator中,首先a被追加了b对象的值,”b”,至此引用a指向的对象,值已经变成ab了。
嗯,然后b=a,引用a的对象地址被赋值给引用b,至此两个引用都指向了同一个对象。
那么后续两句输出,都是ab,没错。
高潮来了,operator方法结束后,main方法中继续往下执行,输出引用a和引用b的值。
引用a指向的是值为ab的对象,输出ab。
引用b指向的是值为ab的对象,输出ab。
没错,以上是我的思路。
程序运行结果打碎了我的认知。
我开始重新思索。
一开始引用a和b都指向各自的对象,碰见方法,方法要了引用a、b各自对象的内存地址,赋值给了自个儿的引用a、b。
a指向的对象被修改,那么main中引用a和operator中的引用a都能看见被修改后的对象,ab。
然后引用b被指向了a的对象,那么此刻b也能看见ab。
出了方法后,main中的a指向没变,输出ab。
引用b指向修改后的对象。。。。
等等!
main方法中的引用地址被改了吗??
电石火花之间,画了一张图。
至此清楚了。
operator中的引用,和main中的引用根本就是两回事!
不要问我为什么一开始我会认为operator中的引用指向被修改,会导致main中的引用也被修改……
我打算把锅甩给“人一到下午脑子就不好使”。