人之所以痛苦,那是因为你在成长。--------magic_guo
java值传递机制:
规则:
java基本数据类型的值传递,传递的是变量的类型的值;
java引用数据类型值传递,传递的是地址值或者null;
1.基本数据类型:
代码:
public class ValueTransTest02 {
public static void main(String[] args) {
int m = 10;
int n = 20;
System.out.println("交换前:m = " + m + ", n = " + n);
int temp = m;
m = n;
n = temp;
System.out.println("交换后:m = " + m + ", n = " + n);
}
}
结果:
交换前:m = 10, n = 20
交换后:m = 20, n = 10
上述代码交换成功,上述代码是我们常用的交换两个变量的值的代码,对此代码我们没有什么疑问。
下面我们来看下面的代码:
代码分析:由于每次交换我们都会使用到交换的代码,因此将交换的代码,抽离出来变成一个函数、以后只要有交换的程序,只需要调用swap()函数即可,这也符合我们对于封装的思想。但是我们看到,结果并非如此,两个变量的值并没有得到交换,这是为什么呢?原因就在于java的基本数据类型值传递,传递的是变量的数据值。
代码:
public class ValueTransTest01 {
public static void main(String[] args) {
int m = 10;
int n = 20;
System.out.println("使用swap交换前:m = " + m + ", n = " + n);
ValueTransTest01 v1 = new ValueTransTest01();
v1.swap(m, n);
System.out.println("使用swap交换后:m = " + m + ", n = " + n);
}
public void swap(int m, int n){
int temp = m;
m = n;
n = temp;
}
}
结果:
使用swap交换前:m = 10, n = 20
使用swap交换后:m = 10, n = 20
内存分析:
声明,java中的局部变量的声明都存在于栈中,在方法中的变量都是局部变量,因此无论是main方法中的m和n,还是swap方法中的m、n和temp都是存在于栈中。
首先我们在mian函数中定义了m=10和n=20,然后创建了类对象来调用swap函数,将main函数中的m和n作为实参传递给swap函数中的形参m和n。此时程序采用压栈的方法,在栈中将swap函数中的m和n进行了赋值,再通过变量temp来交换swap函数中的m和n的值。
最后swap函数执行完毕,输出了swap函数中的m和n,此时在swap函数中,m和n的值是进行了交换,swap中的sout输出的是20和10,
swap函数出栈,随之swap函数中的m和n也销毁。
然后在main函数中的m和n的值并未进行交换。也就是一顿操作之后,并没有改变,因此输出的还是10和20。
主要原因还是java基本数据类型的值传递,传递的是变量的类型的值。
2.引用数据类型
public class ValueTransTest03 {
public static void main(String[] args) {
Data d = new Data();
System.out.println("swap交换前:d.m = " + d.m + ", d.n = " + d.n);
ValueTransTest03 v = new ValueTransTest03();
v.swap(d);
System.out.println("swap交换后:d.m = " + d.m + ", d.n = " + d.n);
}
public void swap(Data data){
int temp = data.m;
data.m = data.n;
data.n = temp;
}
}
class Data{
int m = 10;
int n = 20;
}
结果:
swap交换前:d.m = 10, d.n = 20
swap交换后:d.m = 20, d.n = 10
内存分析:
可以看出,与基本数据类型相反,我们把交换的代码也抽离出来,放在swap函数中,swap函数接收一个Data 类型的对象,却交换成功,原因是什么呢?
java引用数据类型值传递,传递的是地址值或者null;
main函数中创建了一个Data类的对象,此时在栈中有一个d对象存放对空间中地址值,在堆空间中有一块内存空间存放对象的属性m=10和n=20,地址为0x8899;
创建类对象来调用swap函数,将d作为实参传递给swap函数中的形参data,此时data也存放了0x8899的地址值,也就是说data也指向了堆空间中d所指向的内存空间0x8899;
然后声明temp变量来交换堆空间中的m和n的值;最后swap出栈,temp被销毁,data.m,dada.n也被销毁,但是d所指向的m和n的值已经被交换。
----------------------------------------------------------------------------------------------------------------------个人理解,如有不正确的地方,请留言多多指点;