程序设计语言中,将参数传递给方法(或函数)有两种方法。按值传递(call by value)表示方法接受的是调用者提供的值;按引用调用(call by reference)表示方法接受的是调用者提供的变量地址。Java程序设计语言都是采用按值传递。下面通过例题进行说明:
1 public class ParamTest {
2 public static void main(String[] args) {
3 /*
4 *Test1: Methods can't modify numeric parameters
5 */
6 System.out.println("Testing tripleValue:");
7 double percent = 10;
8 System.out.println("Before: percent=" + percent);
9 tripleValue(percent);
10 System.out.println("After: percent=" + percent);
11
12 /*
13 *Test2: Methods can change the state of object parameters
14 */
15 System.out.println("\nTesting tripleSalary");
16 Employee harry = new Employee("Harry", 50000);
17 System.out.println("Before: salary=" + harry.getSalary());
18 tripleSalary(harry);
19 System.out.println("After: salary=" + harry.getSalary());
20
21 /*
22 *Test3: Methods can't attach new objects to object parameters
23 */
24 System.out.println("\nTesting swap");
25 Employee a = new Employee("Alice", 30000);
26 Employee b = new Employee("Bob", 60000);
27 System.out.println("Before: a=" + a.getName());
28 System.out.println("Before: b=" + b.getName());
29 swap(a, b);
30 System.out.println("After: a=" + a.getName());
31 System.out.println("After: b=" + b.getName());
32 }
33
34 public static void tripleValue(double x) {
35 x *= 3;
36 System.out.println("End of method: x=" + x);
37 }
38
39 public static void tripleSalary(Employee x) {
40 x.raiseSalary(200);
41 System.out.println("End of method: salary=" + x.getSalary());
42 }
43
44 public static void swap(Employee x, Employee y) {
45 Employee temp = x;
46 x = y;
47 y = temp;
48 System.out.println("End of method: x=" + x.getName());
49 System.out.println("End of method: y=" + y.getName());
50 }
51 }
52
53 class Employee {
54 private String name;
55 private double salary;
56 public Employee(){}
57 public Employee(String name, double salary){
58 this.name = name;
59 this.salary = salary;
60 }
61
62 public String getName() {
63 return name;
64 }
65
66 public double getSalary() {
67 return salary;
68 }
69
70 public void raiseSalary(double byPercent){
71 double raise = salary * byPercent / 100;
72 salary += raise;
73 }
74 }
程序运行结果为:
从以上例题可以总结Java中方法参数的使用情况:
- 一个方法不能修改一个基本数据类型的参数(即数值型或布尔型)。
- 一个方法可以改变一个对象(数组)参数的状态。
- 一个方法不能让对象参数(数组)引用一个新的对象。
以上内容均参考:java核心技术 卷1 第十版 4.5节
———————————————————————————————————————————
下面通过画内存图说明参数传递过程:
基本数据类型的传递:
- percent将值拷贝给x,percent与x的地址值不同;
- tripleValue()方法将x的值10乘以3后得到10,percent的值不变;
- tripleValue()弹栈后,参数变量x不再使用。
对象或数组作为参数传递:
- Employee harry = new Employee("Harry", 50000); 创建了一个对象变量harry,引用了Employee的一个对象;
- tripleSalary(harry); 将对象harry的地址值传递给参数x, 此时变量harry和x都引用了堆中的同一个Employee对象;并通过方法将这一对象的薪金提高了200%;
- tripleSalary(harry)方法弹栈后,参数变量x不再使用。对象变量harry继续引用那个薪金增至3倍的对象。