本文部分内容引用自Java核心技术++卷1, mm:mwz0
首先回顾一下在程序设计语言中有关将参数传递给方法(或参数)的一些术语。按值调用(call by value)表示方法接收的是调用者提供的值。而按引用调用(call byreference)表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。“按····调用”(call by)是一个标准的计算机科学术语,他用来描述各种程序设计语言(不只是java)中方法参数的传递方式。
Java语言总是采用按值调用。也就是说,方法得到的是所有值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。
例如,看下述的调用:
double percent = 10;
harry.raiseSalary(percent);
不用理会上述raiseSalary方法的具体实现,在方法调用后,percent的值还是10。
下面在对上述情况进行研究。假定一个方法试图将一个参数值增加3倍:
public static void tripleValue(double x){
x = 3 * x;
}
//然后调用这个方法:
double percent = 10;
tripleValue(percent);
==但是上述方法并没有将percent 变成当前值的3倍。调用这个方法后percent的值还是10。==下面看一下具体的执行过程:
根据上述事例看到,一个方法不可能修改一个基本数据类型的参数(数值型或布尔型)。而对象引用作为参数就不同了,可以很容易利用下面的方法进行实现修改。
public class Employee {
private String name;
private double salary;
public Employee(String n, double s) {
name = n;
salary = s ;
}
//省略get set方法
}
public static void tripleSalary(Employee x){
x.raiseSalary(200);//将salary提高200倍
}
当调用:
harry = new Employee(...);
tripleSalary(harry);
方法时,具体的执行过程为:
格局上述事例看到,实现一个改变对象参数状态的方法并不一定是一件难事。方法得到的是对象引用的拷贝,对象引用及其他的拷贝同事引用同一个对象。
==很多程序设计语言(特别是, C++ 和 Pascal) 提供了两种参数传递的方式:值调用和引用调用。很多人认为 Java 程序设计语言对对象采用的是引用调用,实际上, 这种理解是不对的。==由于这种误解具有一定的普遍性,所以下面给出一个反例来详细地阐述一下这个问题
首先,编写一个交换两个雇员对象的方法:
public static void swap(Employee x, Employee y){
Employee temp = x;
x = y;
y = temp;
}
如果Java对象采用的是按引用调用,那么这个方法就应该能够实现交换数据的效果:
Employee a = new Employee("Alice", . . .);
Employee b = new Employee("Bob", . . .);
swap(a, b);
但是,方法并没有改变存储在变量 a 和 b 中的对象引用。swap 方法的参数 x 和 y 被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝。
在方法结束时参数变量 x 和 y 被丢弃了。原来的变量 a 和 b 仍然引用这个方法调用之前所引用的对象(如下图所示)。
这个过程说明:Java语言对对象采用的不是引用传递,实际上是,对象引用是按照值传递的。