Java里方法的参数传递只有一种:值传递。就是将实际参数值的副本(复制品)传入方法内,而参数本身不会受到任何影响。
1、基本类型参数传递
public class valueTransmit {
public static void main(String[] args) {
int a = 6;
int b = 9;
System.out.println("交换前,a的值是:" + a + "; b的值是:" + b);
swap(a, b);
System.out.println("交换结束后,a的值是:" + a + "; b的值是:" + b);
}
public static void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
System.out.println("swap方法里,a的值是:" + a + "; b的值是:" + b);
}
}
运行结果:
交换前,a的值是:6; b的值是:9
swap方法里,a的值是:9; b的值是:6
交换结束后,a的值是:6; b的值是:9
从运行结果得到:swap()方法的a和b只是main()方法里变量a和b的复制品。程序改变的是swap方法栈区中的a、b,mian()方法栈区中的a、b都没有改变。
2、引用类型的参数传递:一样采用的是值传递方式
public static void main(String[] args) {
Student student = new Student();
student.high = 6;
student.age = 9;
System.out.println("交换前,high的值是:" + student.high + "; age的值是:" + student.age);
swap(student); // swap方法里把student赋值为null,main方法的student变量不受影响
System.out.println("交换后,high的值是:" + student.high + "; age的值是:" + student.age);
}
public static void swap(Student student) {
int temp = student.age;
student.age = student.high;
student.high = temp;
System.out.println("swap方法里,high的值是:" + student.high + "; age的值是:" + student.age);
student = null;
}
static class Student {
private int high;
private int age;
public int getHigh() {
return high;
}
public void setHigh(int high) {
this.high = high;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
输出结果:
交换前,high的值是:6; age的值是:9
swap方法里,high的值是:9; age的值是:6
交换后,high的值是:9; age的值是:6
乍看输出结果,当swap方法交换了high和age的值,main方法里high和age的值也交换了。会让我们误以为传入的student是Student对象本身,而不是它的复制品。
其实不然,首先创建一个对象,内存中会有两个东西产生:栈内存中保存了该对象的引用变量,堆内存中保存了对象本身。
一开始,main()方法中调用swap()方法,mian()方法尚未结束,jvm会分别为main()和swap()开辟两个栈区,用于存放局部变量。调用swap()方法是,student变量作为实参传入swap()方法,同样是值传递方式:把实参student赋值给swap方法里的形参,不过这里的student是一个引用(也就是c中的指针),保存的是Student对象的地址值,用于找到堆内存的Student对象。所以swap里面的student也会指向Student对象的堆内存地址。
所以这种引用传递方式也是值传递,关键在于复制的是引用变量的副本,并未复制实际的Student对象。操作的都是同一个对象,因此swap交换后,main方法里面student的属性也会改变。
参考书籍:《疯狂Java讲义》