String作为方法参数:
public class StringTest {
public static void main(String[] args) {
String s1 = new String("string");
change(s1);
System.out.println(s1);
}
public static String change(String s){
s += "test";
return s;
}
}
输出结果s1并未改变。
执行过程:
首先在堆中创建对象string,栈中存储s1,也就是s1对象的引用地址。调用方法时,形参s也指向堆中相同的对象。执行s += "test"后,将会堆中创建另一个String对象,将该对象的地址复制给栈中的形参s1,所以在方法里面s1和s相互独立的,指向不同的对象,s1并未改变。
StringBuilder作为方法参数:
public class StringBuilderTest {
public static void main(String[] args) {
StringBuffer s1 = new StringBuffer("Hello");
StringBuffer s2 = new StringBuffer("Hello");
changeStringBuffer(s1, s2);
System.out.println("s1=" + s1);
System.out.println("s2=" + s2);
}
public static void changeStringBuffer(StringBuffer ss1, StringBuffer ss2) {
ss1.append(" world");
ss2 = ss1;
ss2.append("aa");
}
}
输出结果:
s1=Hello worldaa
s2=Hello
首先知道s1和s2是不相等的,指向堆中两个不同的StringBuilder对象。下面这张图可以很好解释s2未改变的原因。
总结:
String为不可变对象,对其进行操作将生成不一样的对象。
StringBuilder为可变对象,可以直接在原对象上面进行操作。StringBuilder作为方法参数时其实就是传递引用地址。