说Java的引用传递之前,我们先来了解下什么是引用传递和值传递。
值传递
public class Test {
public static void main(String[] args) {
int x=100;
System.out.println("调用方法前:"+x);//调用方法前:100;
sum(x);
System.out.println("调用方法后:"+x);//调用方法后:100;
}
private static void sum(int y) {
y=1000;
}
}
int x=100;
这时候x
的值为100。

sum(x);
这时候x
把的值复制了一份给了sum(int y)
。

y=1000
这时候方法里y
的值就从"100"变成了"1000"

x
的值还是100。

小结
值传递,此传递就是将实参x
的值复制一份给方法sum(int y)
的形参y
,形参的操作不会影响到实参。且当传递方法实参类型为基本数据类型(数字以及布尔值)时,是不可能实参数值的。
引用传递
我们先来看一段代码:
public class Test {
public static void main(String[] args) {
Car c=new Car("奔驰");
System.out.println("调用方法前:"+c.name);//调用方法前:奔驰
updateCar(c);
System.out.println("调用方法后:"+c.name);//调用方法后:宝马
}
static void updateCar(Car a){
a.setName("宝马");
}
}
Car c=new Car("奔驰");
这个时候c
指向了堆内存中的对象。

updateCar(c);
这时候我们把c
的地址传递给a
这时候c
和a
指向同一对象。

a.setName("宝马");
那么这时候"奔驰"就变成了"宝马"。

a
的作用域只在方法内存在,之后a
会被回收。就变成了

小结
引用传递,把实参c
的内存地址值给updateCar(Car a)
方法的形参a
,也就是说在方法执行时实参c
和形参a
指向的是同一内存地址,方法操作的是源数据,所以方法执行时会影响实参。当传递方法参数类型为引用数据类型时,一个方法将修改一个引用数据类型的参数所指向对象的值。
那么问题来了,Java真的有引用传递嘛?
public class Test {
public static void main(String[] args) {
Person x = new Person("赵", "10");
Person y = new Person("孙", "20");
System.out.println("方法调用前:x=" + x.toString());//方法调用前:x=Person{name='赵', age='10'}
System.out.println("方法调用前:y=" + y.toString());//方法调用前:y=Person{name='孙', age='20'}
change(x, y);
System.out.println("方法调用后:x=" + x.toString());方法调用后:x=Person{name='赵', age='10'}
System.out.println("方法调用后:y=" + y.toString());方法调用后:y=Person{name='孙', age='20'}
}
private static void change(Person x, Person y) {
Person temp = y;
y = x;
x = temp;
System.out.println("方法调用中:x=" + x.toString());方法调用中:x=Person{name='孙', age='20'}
System.out.println("方法调用中:y=" + y.toString());方法调用中:y=Person{name='赵', age='10'}
}
}
这时候你会发现引用x
和y
的地址值并没有被调换。
Person x = new Person("赵", "10");
Person y = new Person("孙", "20");
这时候在堆内存创建对象。

change(x,y)
。

x
和y
也指向了同样的内存地址。
Person temp = y;
y = x;
x = temp;
这时候交换地址。


小结
实际上来说Java中并没有引用传递,都是值传递,只是在传递引用类型时,传递的值,是地址值。并没有传递引用。
引用传递
引用传递的话,在调用change(x,y)
方法时内存中应该是这样

