-
在编程语言中(如C、C++),参数传递有两种方式,一种是值传递(值调用 call by value),一种是引用传递(
其实就是传递指针
call by reference)。- 按值调用指的是方法接受的是调用者的值,一个方法不能修改传递值的那个变量本身的值。
- 引用调用指的是方法接受的是调用者提供的变量地址(指针),一个方法可以修改传递引用的那个变量本身的值。
-
方法接受的参数总的来说就是两种类型:
- 基本数据类型(8种)
- 引用数据类型
-
在Java中,参数传递的方式只有值传递。
为什么这么说?请看以下三个实例。
-
实例1:参数为基本数据类型
public class TestCallMethod { public static void main(String[] args) { int x= 10; System.out.println("before call method func(), x is "+x); func(x); System.out.println("after call method func(), x is "+x); } public static void func(int y) { y = y * y; } }
调用func()方法前后,x的值均为10,说明对于基本数据类型采用的是值传递。
-
实例2:参数为引用数据类型
import java.util.Date; public class Employee { private String name; private double salary = 5000; private Date hireDay; public Employee() { } public Employee(String name, double salary, Date hireDay) { this.name = name; this.salary = salary; this.hireDay = hireDay; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public Date getHireDay() { return hireDay; } public void setHireDay(Date hireDay) { this.hireDay = hireDay; } public void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; this.salary = this.salary + raise; } }
import java.util.Date; public class TestCallMethod { public static void main(String[] args) { Date d = new Date(2020, 9, 6); Employee e = new Employee("Tom", 1000, d); System.out.println("before call method changeSalary(), salary is "+e.getSalary()); changeSalary(e); System.out.println("after call method changeSalary(), salary is "+e.getSalary()); } public static void changeSalary(Employee e) { e.raiseSalary(200); } }
- 程序运行结果:
before call method changeSalary(), salary is 1000;
after call method changeSalary(), salary is 3000;
- 说明:
注意:这里执行结果很像是将对象引用按引用传递方式进行参数的传递,但实际的调用过程如上图所示,传递进去的仍然是变量的拷贝,只不过拷贝的变量中值为指向对象的引用(指针),所以方法内通过x变量调用方法修改的也正是原变量所指向的对象的值。
-
实例3:引用数据类型不是引用传递的,只有值传递
import java.util.Date; public class TestCallMethod { public static void main(String[] args) { Date d = new Date(2020,9,6); Employee a = new Employee("Alice", 20000, d); Employee b = new Employee("Bob", 20000, d); System.out.println("before call method swap(), a.getName() is "+a.getName()+", b.getName() is "+b.getName()); swap(a,b); System.out.println("after call method swap(), a.getName() is "+a.getName()+", b.getName() is "+b.getName()); } public static void swap(Employee x, Employee y) { Employee temp = x; x = y; y = temp; } }
- 程序执行结果:
before call method swap(), a.getName() is Alice, b.getName() is Bob
after call method swap(), a.getName() is Alice, b.getName() is Bob
- 说明:
我们在程序中用swap方法交换两个传入的对象引用所指向的对象地址,执行前后发现并不会改变原变量a,b所执行的对象地址,说明Java中引用类型采用的不是引用传递,而是值传递。