先看一下他们的定义:
值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改后,将不会影响到实际参数。
引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改后,将影响到实际参数。
1.值传递,对于java基本类型适用,见代码如下:
public class BaseTypeTransmitTest {
public static void main(String[] args) {
int a = 1;
method(a);
System.out.println("a in main-->" + a);
}
public static void method(int a) {
a = 100;
System.out.println("a in method-->" + a);
}
}
输出:
a in method-->100
a in main-->1
由此可见,基本类型参数传入方法后,方法对该参数进行修改,对原参数不造成影响。为什么呢,因为对于byte short int long float double boolean 这七种基本数据类型,变量是直接存储值的。
执行int a=1;会生成变量a存的值为1,执行method(a);会再生成一个新变量a(注意,是新的变量,遂之后的操作与之前的变量a 无关)存的值也是1,但在执行a=100后,其值变成了100,无论这个新的a的值有多大,都不会对其他变量造成影响
2.引用传递,对于java引用类型适用
talk is cheap,show me the code!
public class ReferTypeTransmitTest {
public static void main(String[] args) {
User user = new User();
user.setName("XiaoMing");
user.setAddress("ShenZhen");
System.out.println("before-->" + user.getName() + " " + user.getAddress());
method(user);
System.out.println("after-->" + user.getName() + " " + user.getAddress());
}
public static void method(User user) {
user.setName("CC");
}
}
class User {
private String name;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
输出:
user in main-->XiaoMing ShenZhen
user in main-->CC ShenZhen
由此可见,由于method方法中对对象user的修改对main方法的user也起了作用。
下面我们逐行解释代码:
User user=new User()这一行代码,发生了三件事:
1.在堆中开辟一块内存,用于存放User对象,其地址为X123456
2.声明了一个User类型的变量user
3.将变量user指向刚生成的User对象,即变量user存的值为X123456,有点类似于C语言中的指针
随后,main方法执行method(user),此时内存中形势如下:
很明显,方法调用又生成了一个user变量,也是指向这个User对象。因此这两个user变量的操作都会相互影响