1. 概述
总的来说,计算机语言给子程序传递参数的方法有两种。第一种方法是按值传递(call-by-value)。这种方法将一个参数值(value)复制成为子程序的正式参数。这样,对子程序的参数的改变不影响调用它的参数。第二种传递参数的方法是引用调用(call-by-reference)。在这种方法中,参数的引用(而不是参数值)被传递给子程序参数。在子程序中,该引用用来访问调用中指定的实际参数。这样,对子程序参数的改变将会影响调用子程序的参数。根据传递的对象不同,Java将使用这两种不同的方法。
2. 传递一个简单类型
在Java中,当你给方法传递一个简单类型时,它是按值传递的。因此,接收参数的子程序参数的改变不会影响到该方法之外。
我们来看如下例子:
class PassByValue {
public void foo (int i, int j) {
i += 1;
j += 1;
}
}
public class Test {
public static void main(String[] args) {
PassByValue p = new PassByValue();
int i = 1;
int j = 2;
System.out.println("Original values of i and j: " + i + " " + j);
p.foo(i, j);
System.out.println("New values of i and j: " + i + " " + j);
}
}
最后,程序的输出结果为:
Original values of i and j: 1 2
New values of i and j: 1 2
可见,在foo
函数内的操作并不影响i
和j
的值,它们并没有从1
和2
变为2
和3
,说明当形参为基本数据类型时,Java是传值方式进行的函数调用。
3. 传递一个对象
当给Java传递一个对象时,它是通过引用传递的。这是因为我们在创建一个类类型的变量时,仅仅是创建了一个类的引用。因此,当我们将这个引用传递给一个方法时,接收它的参数将会指向该参数指向的同一个对象。
我们来看如下例子:
class PassByReference {
int i, j;
public PassByReference(int i, int j) {
this.i = i;
this.j = j;
}
public void foo(PassByReference p) {
p.i += 1;
p.j += 1;
}
}
public class Test {
public static void main(String[] args) {
PassByReference p = new PassByReference(1, 2);
System.out.println("Original values of i and j: " + p.i + " " + p.j);
p.foo(p);
System.out.println("New values of i and j: " + p.i + " " + p.j);
}
}
最后,程序的输出结果为:
Original values of i and j: 1 2
New values of i and j: 2 3
可以看到,在这个例子中,foo
函数中的操作影响了作为参数的对象。
4. 结论
当参数是基本数据类型时,是传值方式调用;而当参数是引用型的变量时,则是传址方式调用。