(博客內容來自於core java卷一)
1. xx調用:程序設計語言中方法參數的傳遞方式:
引用調用(call by reference):表示方法接收的是調用者提供的變量地址。
值調用(call by value):表示方法接收的是調用者提供的值。
命名調用(call by name):已經成為歷史。
2. Java使用值調用,而且只有值調用。也就是說方法得到的是參數值的一個拷貝,並不是參數值本身,所以,方法不能修改傳遞給它的的任何參數變量本身。
看下面代碼:
public class test {
public static void main(String[] args) {
int percent = 10;
tripleValue(percent);
System.out.println(percent);
}
public static void tripleValue(int x){
x = x * 3;
}
}
輸出:10
可以看到,無論怎樣調用這個方法,執行之后,persent的值還是10。具體執行過程:
① x被初始化為persent的一個拷貝(也就是10)。這時x是x,persent是persent,只不過值相同。
② x被乘以3后等於30。但是persent仍然是10。
③ 這個方法結束后,參數變量x不再使用。
3. 然而,方法參數共有兩種類型:基本數據類型(數字,布爾值);對象引用。
一個方法不可能修改一個基本數據類型的參數。而對象引用作為參數就不同了。這時,方法得到一個對象引用的拷貝。對象引用和其拷貝,同時引用着一個對象。
看下面代碼:
public class test {
public static void main(String[] args) {
Circle c = new Circle();
c.r = 1;
bigger(c);
System.out.println(c.r);
}
public static void bigger(Circle c2){
C2.r = c2.r+3;
}
}
class Circle{
int r;
}
輸出:4
具體執行過程:
① c2被初始化為c值的拷貝,這個值是一個對象的引用。
② bigger方法應用於這個對象引用。所以,c2和c同時引用的那個Circle對象的r值就增加了3。
③ 方法結束后,參數變量c2不再使用。c繼續引用這個r值已經增加了3的Circle對象。
4.很多程序設計語言(特別是c++和Pascal)提供了兩種參數傳遞的方式:值調用和引用調用。有些程序員認為java程序設計語言對對象采用的是引用調用,實際上這種理解是不對的。由於這種誤解具有一定的普遍性,所以下面給出一個反例,來詳細闡述一下這個問題。
首先編寫一個交換兩個圓對象的方法:
public static void swap(Circle x,Circle y){
Circle temp = x;
x = y;
y = temp;
}
如果java程序設計語言對對象采用的是引用調用的話,這個方法應該能夠實現交換數據的效果:
Circle a = new Circle(1);
Circle b = new Circle(2);
swap(a,b);
System.out.println(a.r);
System.out.println(b.r);
輸出:
1
2
但是,方法並沒有改變存儲在變量a和b中的對象引用。Swap方法的參數x和y被初始化為兩個對象引用的拷貝,這個方法交換的是這兩個拷貝,a和b中的對象引用並沒有變化。最終,白費力氣,在方法結束時參數變量x和y被丟棄了。這個過程說明:java對對象采用的不是引用調用,而是值傳遞。
5.總結:
(1)一個方法不能修改一個基本數據類型的參數(即數值型和布爾類型值)。
(2)一個方法可以通過對象參數對其引用的對象狀態進行操控。
(3)一個方法不能讓對象參數引用一個新的對象。
注意:c++有值調用和引用調用。引用參數標有&符號。例如,可以輕松低實現void swap(Circle& a,Circle& b)方法,實現修改它們的引用參數的目的。