java 函数返回多个函数值/引用類型認識
java 函数返回多个函数值/引用類型認識
開宗明義,Java中函數的參數傳遞都是值傳遞,不存在引用傳遞。基本數據類型傳遞的是本身的值,而引用類型(對象,數組等)傳遞的同樣值,但是是引用的地址的值。同樣,我們知道值傳遞時,在函數內的改變不影響原參數的值,很好理解(在函數內將int類型自增,執行函數後,原值不會改變)。同樣,套用到引用類型參數時,在函數內引用的改變不影響原來對象的引用。也就是說,如果將傳入的對象重新賦值亦即引用改變,不會影響原來的對象。但是如果在函數內部,在不改變傳入參數的引用的同時,修改對象,這種情況下就修改了原對象,亦即實現了引用傳值。
比如,傳入Integer、String對象時,由於他們沒有改變自身的方法,當重新賦值時,自身的引用發生了改變,因此在函數內改變它們的值,也不會傳遞到函數外。但是如果你傳入一個int或者Object類型的數組(引用類型),並且在函數內改變數組內某一項的值,只要不在函數內重新新建數組(改變了引用),對數組的改變就會導致函數外的數組改變。當對數組某項重新賦值時,就算此時改變了這一個對象的引用,但是整個數組的引用並沒有因此改變。舉例(可能不對,應該是沒錯的)一個大小為2的對象數組,這個數組中三個引用,其中整個對象A的引用為a,其中A指向數組內兩個對象的引用B->b和C-c,此時對B重新賦值B->d,傳入對象A的引用仍然是a,這種情況下改變就會作用到數組本身了。
public static boolean methodLikeCSharpOutParam(int[] result) {
result[0] = 1;
return true;
}
public static boolean methodLikeCSharpOutParamByO(Integer ob) {
ob += 1;
return true;
}
public static boolean methodLikeCSharpOutParamByOs(Object[] os) {
os[0] = 1;
return true;
}
//...
int[] i = new int[1];
System.out.println("int[] before i is " + i[0]);
ClassMethodTest.methodLikeCSharpOutParam(i);
System.out.println("int[] after i is " + i[0]);
Integer io = new Integer(-1);
System.out.println("object before i is " + io);
ClassMethodTest.methodLikeCSharpOutParamByO(io);
System.out.println("object after i is " + io);
Object[] os = new Object[2];
os[0] = -1;
System.out.println("object[] before i is " + os[0].toString());
ClassMethodTest.methodLikeCSharpOutParamByOs(os);
System.out.println("object[] after i is " + os[0].toString());
/* output
int[] before i is 0
int[] after i is 1
object before i is -1
object after i is -1
object[] before i is -1
object[] after i is 1
*/
c++
不管是基本數據類型還是類,只要不使用引用或者指針,參數傳遞都是值傳遞,函數內的改變不會作用于函數外。
class item {
public:
int x;
int y;
item() {
x = 0;
y = 0;
}
};
void add(int i) {
i++;
return;
}
void addd(int& i) {
i = 2;
return;
}
void adddd(int* i) {
*i = 2;
return;
}
void change(item i) {
i.x = 2;
cout<<i.x<<endl;
}
void changeRef(item& i) {
i.x = 2;
cout<<i.x<<endl;
}
void changePoi(item* i) {
i->x = 2;
cout<<i->x<<endl;
}
int main() {
int i = 0;
cout<<"before "<<i<<endl;
adddd(&i);
cout<<"after "<<i<<endl;
item it;
cout<<"item before "<<it.x<<endl;
//change(it);
//changeRef(it);
changePoi(&it);
cout<<"item after "<<it.x<<endl;
system("PAUSE");
return 0;
}
2、3年沒寫過C++代碼連helloworld都不會寫了,還要查資料,在這個main文件裡,在main函數中調用的函數必須要在main函數之上定義,不太懂為什麼。
reference
Updated: 2020-12-20 11:17
Created: 2017-02-19 02:33