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函数内的操作并不影响ij的值,它们并没有从12变为23,说明当形参为基本数据类型时,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. 结论

当参数是基本数据类型时,是传值方式调用;而当参数是引用型的变量时,则是传址方式调用。