方法调用时参数传递的方式有两种:按值传递和按引用传递。
- 按值传递(Pass-by-Value): 当传递基本数据类型(如
int
、float
、boolean
等)作为参数时,实际上传递的是值的副本。也就是说,方法内部对参数进行的修改不会影响到原始变量。 - 按引用传递(Pass-by-Reference): 当传递引用类型(如类对象、数组等)作为参数时,实际上传递的是引用的副本。也就是说,方法内部对参数进行的修改会影响到原始变量。
- 在 Java 中,虽然传递引用类型参数时,形式上看起来像是按引用传递,但实际上还是按值传递。因为传递给方法的仍然是引用的副本,而不是原始的引用本身。
- 这也就是为什么在
swap(Student a, Student b)
方法中交换了形参a
和b
的引用,但并没有影响到main
函数中的变量a1
和b1
的引用。
示例:
package Test;
public class Func {
public static void main(String[] args) {
int a=1;
int b=2;
swap(a,b);
System.out.println(a+" "+b);
Student a1=new Student();
a1.name="张三";
Student b1=new Student();
b1.name="李四";
swap(a1,b1);
System.out.println(a1.name+" "+b1.name);
swap1(a1,b1);
System.out.println(a1.name+" "+b1.name);
}
public static void swap(Student a, Student b){
Student c=a;
a=b;
b=c;
}
public static void swap(int a, int b){
int temp=a;
a=b;
b=temp;
}
public static void swap1(Student a, Student b){
String name=a.name;
a.name=b.name;
b.name=name;
}
}
class Student{
String name;
int age;
}
上图为输出结果
为什么出现这样的结果,前两个打印出结果没有实现交换,最后一个从结果上来说实现了交换
- 当调用
swap(a, b)
时,实际上是将a
和b
的值复制给了函数swap
中的两个新变量int a
和int b
。在函数swap
内部,对这两个新变量进行了交换操作。简单来说,当调用swap(a, b)
时,函数swap
操作的是a
和b
的副本,而不是原始的a
和b
。所以在main
函数中,a
和b
的值没有发生改变。 - 同理在函数
swap(Student a, Student b)
中,创建一个临时变量c
来交换参数a
和b
的引用。当调用swap(a1, b1)
时,函数会创建两个新的引用变量c
和a
,并将a1
的引用复制给了c
,将b1
的引用复制给了a
。然后,将c
的值(也就是a1
的引用)赋给了b
,完成了a
和b
引用的交换。 - 在
swap1(Student a, Student b)
中,我们获取到了a.name和b.name的属性,并对原始字符串进行了修改。这里成功交换仅限于交换对象的属性,而不是交换对象本身。也就是说,a
和b
对象的引用并没有发生改变,仍然指向原来的对象。只是对象的属性值被交换了。