在C++中,函數調用時有傳值調用和傳址調用兩種方式,但在Java中只有傳值調用一種方式。Java中的方法參數爲那幾種基本數據類型的狀況跟C++中同樣,傳入的只是變量的拷貝。而當參數類型爲類對象時,則有可能會誤覺得是傳址調用。函數
如今此舉出例子並加以說明 測試
public class AClass {
int data;
}spa
該類爲做爲測試用的類,裏面只有一個域。對象
public class ParameterTest {
public static void main(String[] args) {
AClass a = new AClass();
a.data = 10;
test1(a);
System.out.println(a.data);
}
public static void test1(AClass aClass) {
aClass.data = 0;
}
}class
執行過程:test
先構造一個新的實例,併爲其賦值爲10。再調用方法test1(),在該方法中將data的值設爲0。而後程序又回到方法體外面,輸出結果爲0。變量
在此看來,貌似方法調用時傳的是地址,由於對data域的改動影響到了方法體外面。那麼再來看下一個例子。grid
public class ParameterTest {
public static void main(String[] args) {
AClass a = new AClass();
a.data = 10;
test2(a);
System.out.println(a.data);
}
public static void test2(AClass aClass) {
AClass b = new AClass();
b.data = 100;
aClass = b;
}
}數據類型
此時一樣構造一個新的實例,並將其數據域賦值爲10,再調用方法test2()。與方法test1()不一樣的是,在該方法中又定義了一個新的實例(其值爲100),而後使傳入的參數指向該實例。該方法執行完畢後,輸出的結果爲10。看來在方法體中的操做出了方法後就沒有做用了,這樣的話又不像是在傳址了。那是爲何呢?引用
構造實例併爲其數據賦值後(以下圖),產生一個指向實例的引用a:
調用方法test1()時(以下圖),a'爲引用a的一個拷貝,它也指向當前的實例:
當在test1()的方法體中修改數據域的值時(以下圖):
由於在方法體中,傳入的引用的拷貝指向沒有發生改變,因此它修改了數據域的值後會影響到原來的實例的值。
一樣,構造實例併爲其賦值後,再調用方法test2()。在方法體中傳入的依然是引用的一個拷貝。以下圖:
在方法test2()中構造一個新的實例併爲其賦值100後,以下圖:
在方法體中爲傳入的引用的拷貝再次賦值後,它指向了方法體中產生的實例b,以下圖:
通過上圖,能夠看出:在方法體中傳入的引用的拷貝指向確實改變了,它指向了新構造的實例b。可是在方法體外面,原來的實例指向仍是沒變,因此這回的輸出仍是10。
在Java的方法調用中,方法中的參數是以傳值的形式進行的,無論它是什麼數據類型。若是是基本數據類型,則就是傳入該值的一個拷貝;若是是類類型,則傳入的是引用的一個拷貝。歸根結底仍是傳的值。