首先写一个简便的Employee,以便测试使用。
class Employee { private String name; public Employee(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
第一次测试:
然后写一个函数,传入一个Emplyee对象,修改name,如果函数执行完毕原来的employee的name值发生变化,按照我们的理解,会认为是引用传递。
public static void main(String[] args) { Employee a = new Employee("Alice"); Employee b = new Employee("Bob"); changeName(a); System.out.println(a.getName()); System.out.println(b.getName()); } public static void changeName(Employee x) { x.setName("fly"); }
执行结果:
fly
Bob
第二次测试:
但是还有一个测试用例,交换两个对象。如果是引用传递,函数执行结束后,两个对象的名字会发生交换。现在来试一下。
public static void main(String[] args) { Employee a = new Employee("Alice"); Employee b = new Employee("Bob"); swap(a, b); System.out.println(a.getName()); System.out.println(b.getName()); } public static void swap(Employee x, Employee y) { Employee t = x; x = y; y = t; }
执行结果:
Alice
Bob
然而他们并没有发生任何变化。什么情况?!又变成值传递了吗?
最后的答案确实是值传递。第一个例子中让大家感觉是引用传递的原因是:传入函数的值是对象引用的拷贝。(用c语言的说法是指针的拷贝,也就是说地址的拷贝。)
第三次测试:
这个时候我们再写最后一个例子,在swap函数里修改x的name值。
public static void swap(Employee x, Employee y) { Employee t = x; x = y; y = t; x.setName("joyce"); }
执行结果:
Alice
joyce
看,x交换后的引用是b的,所以修改x后,b会发生变化。
第二次测试因为没有发生修改,函数结束后就什么都没了,毕竟只是引用的拷贝嘛~
java是值传递,值是对象引用的拷贝。