在Java中,当对象作为参数传递时,究竟是值传递还是引用传递?
官方明确表明:java方法中传递对象 只有一种方式:值传递。
下面分两种情况讨论:基本类型(String为不可变类,和基本类型相似)和引用类型:
- 参数为基本类型:
public class StackTest2 {
public static void main(String[] args) {
int a = 5;
int b = 6;
changeInt(a, b);
System.out.println("a:" + a);
System.out.println("b:" + b);
}
// 参数a, b 为基本类型数据
private static void changeInt(int a, int b) {
a = 7;
b = a;
b = 8;
}
}
运行得到结果:
a:5
b:6
结论:当基本数据类型(String不可变量与之类似)作为参数传递时,传递的是实参值的拷贝,无论在函数中怎么操作这个拷贝的值,实参的值都不会发生变化.
- 参数为引用对象(重要):
public class StackTest {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("Jack Ma");
StringBuilder sb2 = new StringBuilder("Architect Gong");
changeStr(sb1, sb2);
System.out.println("sb1:" + sb1);
System.out.println("sb2:" + sb2);
}
// 参数sb1, sb2 为引用数据类型
private static void changeStr(StringBuilder sb1, StringBuilder sb2) {
sb1.append(" - 风~");
sb2 = sb1;
sb2.append(" 没有方向的吹来~");
}
}
运行得到结果:
sb1:Jack Ma - 风~ 没有方向的吹来~
sb2:Architect Gong
结论:当引用类型对象作为参数传递时,实际上传递的是:引用的拷贝
- 图文说明:
内存分配:new()出来的对象,内存分配与堆中,方法存在于栈中。
sb1,sb2分别指向堆中的对象地址aaa,bbb;当作为参数传递方法时,会传递对象的拷贝作为形参sb1,sb2;注意:由于可指向实际地址,所以可间接改变实际的对象的值。但是,由于sb2 = sb1,sb2重新被赋值,从而被改变指向了aaa,故sb2.append()操作改变的仍然是aaa。
结果:aaa对象被改变两次,bbb对象没发生任何变化。