在Java中方法的参数传递方式只有一种,那就是值传递.所谓的值传递,就是在向方法的形参传递实际参数的时候,是传递实际参数的副本,而对参数本身没有任何影响,在这里,主要分为两种值类型的传递.
第一种是基本数据类型的传递
这是比较容易理解的一种值传递,比较经典的例子就是swap方法用来交换两个值.
public class testInt{
public staticvoid swap(int a,int b){
int temp= 0;
temp = a;
a = b;
b = temp;
System.out.println("在swap函数内部的a = " + a +" b="+b);
}
public staticvoid main(String[] args){
int a= 1;
int b= 2;
System.out.println("运行swap函数之前的a = " + a +" b="+b);
swap(a,b);
System.out.println("运行了swap函数之后的a = " + a +" b="+b);
}
}输出的结果是
运行swap函数之前的a = 1 b= 2
在swap函数内部的a = 2 b= 1
运行了swap函数之后的a = 1 b= 2
由此可见,swap函数并未对main函数中的a和b互换值成功,但是a和b的数值又确实是传进了swap函数中;
看一下内存的过程
首先,main函数进栈,然后在栈中生成了a和b两个变量,,紧接着是将swap函数进栈,它也有个栈区,并且形参的值传入栈中,
现在开始进行swap的函数执行,执行了swap方法之后,swap中的值变化,由此可见,swap中的值交换成功,但是main函数的值并没有改变,所以这个函数并不能完成交换值
那么如何完成这个交换呢?
public class testInt{
static int a = 1;
static int b= 2;
public staticvoid swap(){
int temp= 0;
temp = a;
a = b;
b = temp;
System.out.println("在swap函数内部的a = " + a +" b="+b);
}
public staticvoid main(String[] args){
System.out.println("运行swap函数之前的a = " + a +" b="+b);
swap();
System.out.println("运行了swap函数之后的a = " + a +" b="+b);
}
}
这样运行结果就变成了
运行swap函数之前的a = 1 b= 2
在swap函数内部的a = 2 b= 1
运行了swap函数之后的a = 2 b= 1
即交换成功.
第二种引用类型在方法中的值传递,这个是一个容易造成误解的值传递,但其实我们只要记住,Java中方法的参数传递方式只有一种值传递一种方式就好了.但是,引用类型究竟在内存中是怎样操作的呢?
例如:
//定义一个类来存放数据
class Data{
int a;
int b;
}
public class DataSwap {
public static void swap(Datad){
int temp = d.a;
d.a = d.b;
d.b = temp;
System.out.println("在swap函数内部的a = " + d.a +" b="+d.b);
}
public static void main(String[]args){
Data data = new Data();
data.a = 1;
data.b = 2;
System.out.println("运行swap函数之前的a = " + data.a +" b="+data.b);
swap(data);
System.out.println("运行了swap函数之后的a = " + data.a +" b="+data.b);
}
}
运行结果是
运行swap函数之前的a = 1 b= 2
在swap函数内部的a = 2 b= 1
运行了swap函数之后的a = 2 b= 1
从结果看来,是交换成功了,这又是为什么呢?
看一下内存中发生了什么?
接下来,将d对象传给swap方法,如下图所示,也是将d的副本传给了swap函数;
如图所示,将d的副本传给swap,但是d的副本的值和d没有区别都是指向内存中相同的地址,所以swap的操作也是对原内存的操作,所以可以交换成功,如果我们将swap中的d赋值为null,这样的情况下,main栈区的d对象仍然可以访问到a,b的值,由此可见,swap的d和main中的d完全是两种不同的概率,并不影响.