方法在调用的时候参数是如何传递的呢?其实在调用的时候参数传递给方法,这个过程就是赋值的过程,参数传递和“赋值规则”完全相同,只不过参数传递在代码上看不见“=”运算符。我们先来深入的研究一下“赋值规则”吧!
public class AssignmentTest {
public static void main(String[] args) {
//基本数据类型
int a = 10;
int b = a; //a赋值给b,a把什么给了b?
//引用数据类型
Bird bird1 = new Bird("polly");
//bird1赋值给bird2,bird1把什么给了bird2?
Bird bird2 = bird1;
}
}
class Bird {
String name;
public Bird(){}
public Bird(String _name){
name = _name;
}
}
在以上程序当中,有两个疑问,第一个:a赋值给b,a把什么给了b?第二个:bird1赋值给bird2,bird1把什么给了bird2?
其实a,b,bird1,bird2就是4个普通的变量,唯一的区别只是a和b都是基本数据类型的变量,bird1和bird2都是引用数据类型的变量(或者说都是引用),a变量中保存的那个“值”是10,bird1变量中保存的那个“值”是0x8888(java对象内存地址),本质上来说10和0x8888都是“值”,只不过一个“值”是整数数字,另一个“值”是java对象的内存地址,大家不要把内存地址特殊化,它也是一个普通的值。
那么“赋值”是什么意思呢,顾名思义,赋值就是把“值”赋上去。a赋值给b,本质上不是把a给了b,而是把a变量中保存的“值10”复制了一份给了b。bird1赋值给bird2本质上不是把bird1给了bird2,而是把bird1变量中保存的“值0x8888”复制了一份给了bird2。请看以下内存图的变化:
图9-33:赋值原理图
通过以上内存图我们可以看出“赋值”运算的时候实际上和变量的数据类型无关,无论是基本数据类型还是引用数据类型,一律都是将变量中保存的“值”复制一份,然后将复制的这个“值”赋上去。他们的区别在于,如果是基本数据类型则和堆内存当中的对象无关,如果是引用数据类型由于传递的这个值是java对象的内存地址,所以会导致两个引用指向同一个堆内存中的java对象,通过任何一个引用去访问堆内存当中的对象,此对象内存都会受到影响。我们来验证一下,让a++,a应该变成了11,但是b不会变,让bird1.name = “波利”,然后输出bird2.name的结果肯定也是”波利”,请看代码以及运行结果:
public class AssignmentTest {
public static void main(String[] args) {
//基本数据类型
int a = 10;
int b = a; //a赋值给b,a把什么给了b?
a++;
System.out.println("a = " + a);
System.out.println("b = " + b);
//引用数据类型
Bird bird1 = new Bird("polly");
//bird1赋值给bird2,bird1把什么给了bird2?
Bird bird2 = bird1;
System.out.println("bird1's name = " + bird1.name);
System.out.println("bird2's name = " + bird2.name);
bird1.name = "波利";
System.out.println("bird1's name = " + bird1.name);
System.out.println("bird2's name = " + bird2.name);
}
}
class Bird {
String name;
public Bird(){}
public Bird(String _name){
name = _name;
}
}
运行结果如下图所示:
图9-34:赋值原理测试
上面我就提到了,方法调用时参数的传递和赋值运算符的原理完全相同,那么请大家根据以上内容所学,画出以下程序的内存图,以及推算它们的执行结果:
public class ParameterTransferTest01 {
public static void main(String[] args) {
int i = 10;
add(i);
System.out.println("main's i = " + i);
}
public static void add(int i){
i++;
System.out.println("add's i = " + i);
}
}
public class ParameterTransferTest02 {
public static void main(String[] args) {
User user = new User(20);
add(user);
System.out.println("main's user age = " + user.age);
}
public static void add(User user) {
user.age++;
System.out.println("add's user age = " + user.age);
}
}
class User{
int age;
public User(){}
public User(int _age){
age = _age;
}
}