项目场景:
这是一道之前忽视了的Java参数传递的题目,甚至做的时候解题方向都错了。
问题描述:
题目是这样的:
public class Test {
public static void main(String[] args) {
StringBuffer a = new StringBuffer("a");
StringBuffer b = new StringBuffer("b");
solution(a, b);
System.out.println(a + "," + b);
}
public static void solution(StringBuffer a, StringBuffer b) {
a.append(b);
b = a;
}
}
那么这里会输出什么呢?
答案是:ab,a
原因分析:
【记录一下研究的步骤】:
(1)首先判断是不是因为static导致的?发现去掉static还是输出 ab,b
(2)如果不是StringBuffer,而是String?发现输出 a,b 于是将问题定位到StringBuffer上
(3)如果是StringBuilder会不会也出现这个结果? 发现StringBuilder也输出 ab,b
java有没有引用传递?
答案是No! Java没有引用传递!
首先Java是没有引用传递的,只有值传递!即使传的是对象或者数组,也是实参将引用进行拷贝,之后将副本进行传递给形参。
这个问题很好理解,不明白的可以参考我的这篇:【 java有没有引用传递?】
解决方案:
因为传递的是对象的引用副本,所以形参和实参所存储的引用地址指向的是同一个堆中的StringBuffer对象!,那么对这个同一个对象进行apped
也就是说:下面solution中的形参接收的引用地址就是main中传来的引用地址,两个a和两个b指向的分别是相同的StringBuffer对象
(1)首先a.append(b);在堆中a的StirngBuffer追加b中的字符串值
(2)b = a;这里虽然将a的引用地址传给b,但是由于Java是值拷贝。这里面的b只是一个拷贝的索引…不逃逸的情况下是不会影响Main栈帧中的变量值的。
(3)而回到Main方法中,a所指向的对象刚刚在solution中进行了追加append操作,但是b指向的对象并没有改动。
因此输出 ab,b
public class Test {
public static void main(String[] args) {
StringBuffer a = new StringBuffer("a");
StringBuffer b = new StringBuffer("b");
solution(a, b);
System.out.println(a + "," + b);
}
public static void solution(StringBuffer a, StringBuffer b) {
a.append(b);
b = a;
}
}