首先,你要知道Java中方法的参数传递机制只有值传递,并不存在引用传递的说法,或者说所谓的引用传递实则也是值传递。
什么是值传递?所谓值传递,就是将实际参数的副本(复制品)传入方法,而参数的本身不会受到任何的影响。
1、基本数据类型的值传递
public class Swap {
public static void swap(int a ,int b){
int tmp = a;
a = b;
b = tem;
System.out.println("Swap方法里," + "a=" + a + ";" +"b=" +b);
}
public static void main(String[] args){
int a = 1;
int b = 2;
System.out.println("初始赋值时,"+ "a=" + a + ";" +"b=" +b);
swap(a,b);
System.out.println("交换结束后,"+ "a=" + a + ";" +"b=" +b);
}
}
运行结果:
初始赋值时,a=1;b=2
Swap方法里,a=2;b=1
交换结束后,a=1;b=2
分析:swap()方法里面a、b的值是2、1,交换方法结束后,a、b的值依然是1、2。这也说明了swap()方法的a、b只是main()方法变量a、b的复制品。当程序执行swap()方法时,系统将main()方法中的a、b变量作为参数值传入swap()方法,传入的只是a、b的副本。
2、引用类型的值传递
class DataWrap{
int a;
int b;
}
public class ReferenceTransferTest {
public static void swap(DataWrap dw){
//下面三行代码实现dw的 a、b两个成员变量的值交换
//定义一个临时变量来保存dw对象的a成员变量的值
int tmp = dw.a;
dw.a = dw.b;
dw.b = tmp;
System.out.println("swap方法里,a成员变量的值是" + dw.a +";b成员变量的值是 "+ dw.b);
}
public static void main(String[] args){
DataWrap dw = new DataWrap();
dw.a = 1;
dw.b = 2;
System.out.println("初始赋值时,a成员变量的值是" + dw.a + ";b成员变量的值是 " + dw.b);
swap(dw);
System.out.println("交换结束后,a成员变量的值是" + dw.a + ";b成员变量的值是 " + dw.b);
}
}
运行结果:
初始赋值时,a成员变量的值是1;b成员变量的值是 2
swap方法里,a成员变量的值是2;b成员变量的值是 1
交换结束后,a成员变量的值是2;b成员变量的值是 1
分析:dw只是一个引用变量,系统复制了dw传入swap()方法里,但并未复制DataWrap对象。当程序在swap()方法里操作dw形参时,由于dw只是一个引用变量,故实际操作的还是堆内存的DataWrap对象。此时不管操作main()方法里的dw变量,还是操作swap()方法里的dw参数,其实操作他们所引用指向的DataWrap对象。
总的来说,方法的参数传递只有值传递,当传入的是基本数据类型时,传入的是基本数据类型数据的副本,无论方法里对数据作什么操作,都不会影响原来数据(它直接创建了另一个栈区储存并操作);当传入的是引用类型时,传入的是引用变量的副本(注意不是对象),当在方法通过引用变量对它所指向的对象进行操作时,原来的引用变量所指向的对象也就会随着改变(因为两者所指向的就是同一个对象)。
文章参考:《疯狂Java讲义》一书。