總的來說,計算機語言給子程序傳遞參數(shù)的方法有兩種。第一種方法是按值傳遞(call-by-value )。這種方法將一個參數(shù)值(value )復(fù)制成為子程序的正式參數(shù)。這樣,對子程序的參數(shù)的改變不影響調(diào)用它的參數(shù)。第二種傳遞參數(shù)的方法是引用調(diào)用(call-by-reference )。在這種方法中,參數(shù)的引用(而不是參數(shù)值)被傳遞給子程序參數(shù)。在子程序中,該引用用來訪問調(diào)用中指定的實際參數(shù)。這樣,對子程序參數(shù)的改變將會影響調(diào)用子程序的參數(shù)。你將看到,根據(jù)傳遞的對象不同,Java 將使用這兩種不同的方法。
在Java 中,當(dāng)你給方法傳遞一個簡單類型時,它是按值傳遞的。因此,接收參數(shù)的子程序參數(shù)的改變不會影響到該方法之外。例如,看下面的程序:
// Simple types are passed by value.
class Test {
void meth(int i,int j) { i *= 2;j /= 2;
}
}
class CallByValue {
public static void main(String args[]) {
Test ob = new Test();
int a = 15,b = 20;
System.out.println("a and b before call: " +
a + " " + b);
ob.meth(a,b);
System.out.println("a and b after call: " +
a + " " + b);
}
}
該程序的輸出如下所示:
a and b before call: 15 20
a and b after call: 15 20
可以看出,在meth( ) 內(nèi)部發(fā)生的操作不影響調(diào)用中a和b的值。它們的值沒在本例中沒有變?yōu)?0和10。
當(dāng)你給方法傳遞一個對象時,這種情形就會發(fā)生戲劇性的變化,因為對象是通過引用傳遞的。記住,當(dāng)你創(chuàng)建一個類類型的變量時,你僅僅創(chuàng)建了一個類的引用。因此,當(dāng)你將這個引用傳遞給一個方法時,接收它的參數(shù)將會指向該參數(shù)指向的同一個對象。這有力地證明了對象是通過引用調(diào)用傳遞給方法的。該方法中對象的改變確實影響了作為參數(shù)的對象。例如,考慮下面的程序:
// Objects are passed by reference.
class Test { int a,b;
Test(int i,int j) {a = i;b = j;
}
// pass an object
void meth(Test o) {
o.a *= 2;
o.b /= 2;
}
}
class CallByRef {public static void main(String args[]) { Test ob = new Test(15,20);
System.out.println("ob.a and ob.b before call: " +
ob.a + " " + ob.b);
ob.meth(ob);
System.out.println("ob.a and ob.b after call: " +
ob.a + " " + ob.b);
}
}
該程序產(chǎn)生下面的輸出:
ob.a and ob.b before call: 15 20
ob.a and ob.b after call: 30 10
正如你所看到的,在這個例子中,在meth ( ) 中的操作影響了作為參數(shù)的對象。
有趣的一點是,當(dāng)一個對象引用被傳遞給方法時,引用本身使用按值調(diào)用被傳遞。但是,因為被傳遞的值指向一個對象,該值的拷貝仍然指向它相應(yīng)的參數(shù)所指向的同一個對象。
注意:當(dāng)一個簡單類型傳遞給一個方法時,使用按值傳遞。對象傳遞則按引用傳遞。