今天遇到个面试题
[code="java"]public class NewExample {
public static void main(String[] args) {
StringBuffer a = new StringBuffer("A");
StringBuffer b = new StringBuffer("B");
op(a,b);
System.out.println(a+","+b);
}
static void op(StringBuffer a,StringBuffer b){
b.append(a);
a=b;
}
}
[/code]
输出结果为"A,BA”,请帮我分析一下呢
真心对ITEye的这个图片编辑的东西无语了,传个大的不能完全显示,删掉了还占那么大位置,只能把图片变小点了:
[img]http://dl.iteye.com/upload/picture/pic/119126/1a8c0c62-5ac6-3bb1-9d5e-eb62f627b45c.jpg[/img]
考题:引用传递
拷贝的是对象在栈中的地址 而不是修改指针
static void op(StringBuffer a,StringBuffer b){
b.append(a);
a=b; //此处的a是op方法的局部变量
}
a=b 在那个方法里面a对象=b对象,a的引用指向b,方法内a的值为BA 但是a只是方法内的局部变量,并不能影响原来的a变量,出方法后,a还原,还是指向原来的堆对象值A,因为是按地址传递,而且在方法内改变的是b的值,但对象没变,所以值保存是BA
内存分析:
StringBuffer a = new StringBuffer("A"); :对象是有两块内存的,在堆里分配一块内存,值为"A",然后栈里也有一块内存用来指向刚才堆创建的内存,里面的值是a对象的地址
当调用op方法时,系统为参数a, b分配两块栈内存,然后把main方法中a, b对象的地址传给它
执行b.append(a);内存中是相当于创建副本重新赋值,也就是在堆重新分配一块内存值为"BA",所以此时b = "BA"
然后执行a = b;实际上就是a也指向b刚才分配的堆内存,此时a = "BA"
方法调用结束,系统回收方法中参数的内存,此时main方法中的a的值还是"A",因为main方法中a对象的引用没有变化,而b的堆内存里的值已经变为"BA"了
此题考查的是值传递还是引用传递,append方法会对改变值,是引用传递,而 = 是值传递,值不受影响
没什么可奇怪的,你传递任何两个类,进入,让a=b,原来的a的值都不会改变
因为在当成形参传进去后,会成为这个方法的局部变量
之所以你改了b,是因为你就在b的地址上改的,当你让a=b,这是你相当于让a这个局部变量地址指向b,这时你操作a也是在改b这个地址的数据
当你运行跳出这个方法,方法里边的a,b是你第一个方法的局部变量,a指向a的地址,b指向b的地址
这下你明白b的值变了,而a的值没变的原因了吧
在此有个建议,不要把形参的名字跟你传入的名字取得一样,这样会混淆初学者,不知道自己改了什么
方法中的a b都为局部变量,分别指向两个地址,append是修改地址内的值,而=只是改变局部变量的地址指向而已,所以主方法中a值不变
传个图片试试
[img]http://dl.iteye.com/upload/picture/pic/119118/9ba73ba6-beae-374c-8470-9514ea46220d.jpg[/img]