1. 方法参数的传递方式
“按…………调用”(call by)是一个标准的计算机科学术语,用来描述各种程序设计语言中方法参数的传递方式。
方法参数的传递方式:
- 按值调用(call by value)表示方法接收的是调用者提供的值。
- 按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。
方法可以修改按引用传递的变量的值,而不能修改按值传递的变量的值。
Java 程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个副本。具体讲,方法不能修改传递给它的任何参数变量的内容。
public class ParamTest {
public static void tripleValue(double x) {
x = 3 * x;
System.out.println("方法结束时,x = " + x);
}
public static void main(String[] args) {
double x = 10;
System.out.println("调用方法前,x = " + x);
ParamTest.tripleValue(x);
System.out.println("调用方法后,x = " + x);
}
}
打印结果:
调用方法前,x = 10.0
方法结束时,x = 30.0
调用方法后,x = 10.0
一个方法不可能修改一个基本数据类型的参数。
实现一个改变对象参数状态的方法完全是可以的,也相当常见。理由很简单,方法得到的是对象引用的副本,原来的对象引用和这个副本都是同一个对象。
有些程序员认为 Java 程序设计语言对对象采用的是按引用调用,实际上,这种理解是不对的。下面是一个反例。
import java.util.Objects;
public class ParamTest {
public static void swap(Employee x, Employee y) {
Employee temp = x;
x = y;
y = temp;
}
public static void main(String[] args) {
Employee a = new Employee("A", 10000);
Employee b = new Employee("B", 5000);
System.out.println(a);
System.out.println(b);
// A 的工资增加 200%
a.raiseSalary(200);
// 交换 a 和 b 的对象
ParamTest.swap(a, b);
System.out.println("调用 Employee 对象交换方法后");
System.out.println(a);
System.out.println(b);
}
}
class Employee {
private String name;
private double salary;
public Employee(String name, double salary) {
Objects.requireNonNull(name, "The name cannot be null");
this.name = name;
this.salary = salary;
}
/**
* 增加工资
* @param byPercent 百分比
*/
public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
public String toString() {
String str = "%s[name=%s,salary=%s]";
return String.format(str, getClass(), name, salary);
}
}
打印结果:
class Employee[name=A,salary=10000.0]
class Employee[name=B,salary=5000.0]
调用 Employee 对象交换方法后
class Employee[name=A,salary=30000.0]
class Employee[name=B,salary=5000.0]
从执行的结果中可以看到,变量 a 和变量 b 的对象没有交换,这说明:Java 程序设计语言对对象采用的不是按引用调用。变量 a 的对象状态发生了改变,说明,Java 程序设计语言对象方法参数可以改变对象的状态。
Java 程序设计语言对对象采用的不是引用调用,实际上,对象引用是按值传递的。
下面总结一下在 Java 中方法参数能做什么和不能做什么:
- 方法不能修改基本数据类型的参数(即数值型或布尔型)
- 方法可以改变对象参数的状态。
- 方法不能让一个对象参数引用一个新的对象。