Java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,因此Java中的引用区别与C++中的引用,特别是,方法不能修改传递给它的任何参数变量的内容。
public static void addx(int y) {
y += y;
}
int x = 10;
addx(x);
上述代码执行后x仍然是x,具体执行过程为:y被初始化为x值的一个拷贝,y加倍,但x保持不变,方法结束后,y也失去作用。
Java中方法参数有两种,一是基本数据类型如上所示,二是对象引用。对于基本数据类型,通过上述代码已知方法不可能修改一个基本数据类型。但是,对于对象引用,可以通过方法修改所引用对象的域值。如:
public static void tripleSalary(Employee x) {
x.raiseSalary(200);
}
Employee harry = new Employee(...);
tripleSalary(harry);
上述代码执行后,对象x的域salary将被改变。该过程为:x被初始化为harry值的拷贝,这里是一个对象的引用。raiseSalary方法应用于这个对象引用。x和harry同时引用的那个Employee对象的salary被改变,方法结束后,参数变量x不再使用,对象harry继续引用那个域值已被改变的对象。但是,Java的这种引用绝对不能理解为对对象采用的是引用调用。考虑如下代码段:
如果Java采用的是对象引用调用,则上述代码段将实现两个对象互换。但实际执行完后,harry仍是harry,potter仍是potter。方法并没有改变存储在harry和potter中的对象引用。swap方法的参数x和y被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝,在方法结束时参数变量x和y都被丢弃了。原来的变量harry和potter仍然引用这个方法调用前所引用的对象。public static void swap(Employee x, Employee y) { Employee temp = x; x = y; y = tmp; } Employee harry = new Employee(...); Employee potter = new Employee(...); swap(harry, potter);
综上,Java程序设计语言对对象采用的不是引用调用,实际上,对象引用进行的是值传递。
*一个方法不能修改一个基本数据类型的参数
*一个方法可以改变一个对象参数的状态
*一个方法不能让对象参数引用一个新的对象。
另外,如果某个对象的包含一个对象域,且该域为私有的,则返回这个域时应返回其克隆。如:
public Time { ... private Date day; ... public Date getDay() { return day.clone(); } ... }
否则,day对象的域值将可以被改变,失去了private的意义。
C++有值调用和引用调用。
void tripleSalary(int& x); void swap(Employee& x, Employee& y);
上述都可以实现引用值的改变。