函式中引數傳值
1、基本資料型別傳值
當函式中傳入的引數為基本資料型別時,函式中對傳入引數的操作不會對函式外的資料產生影響。由於基本資料型別的變數名指向的是具體的數值,在函式內部,相當於將引數進行了拷貝,函式內只對拷貝後的引數進行操作。
- 基本資料型別
public class ParamsTrans {
/**
* 基本資料型別傳值
* @param a 基本資料型別
*/
private static void primitiveType(int a){
a = 1;
}
public static void main(String[] args) {
int primitiveParam = 0;
ParamsTrans.primitiveType(primitiveParam);
System.out.println(primitiveParam);
}
}
// 結果:0
結果分析:基本資料型別primitiveParam初始值為0,在函式中對其值進行修改,輸出值仍為0,說明函式內的操作未生效。
- 基本資料型別陣列
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ParamsTrans {
/**
* 基本資料型別陣列傳值
* @param d
*/
private static void arrayType(int[] d){
d[0] = 1;
System.out.println("d hashcode:" + d.hashCode());
}
public static void main(String[] args) {
int[] arrayParam = new int[2];
arrayType(arrayParam);
System.out.println(Arrays.toString(arrayParam));
System.out.println("arrayParam hashcode:" + arrayParam.hashCode());
}
}
// 結果:
// d hashcode:460141958
// [1, 0]
// arrayParam hashcode:460141958
結果分析:基本資料型別陣列與基本資料型別在引數傳值時,具有相同特性。
2、引用資料型別傳值
當函式中傳入的引數為引用資料型別時,函式中對傳入引數的操作會對函式外的資料產生影響。由於引用變數指向物件的記憶體地址,在函式內部,引數只是建立了一個新的變數指向同一個物件,函式中對此物件進行操作,函式外的引用變數也會相應改變。
import java.util.ArrayList;
import java.util.List;
public class ParamsTrans {
/**
* 引用資料型別傳值
* @param b 引用資料型別
*/
private static void QuoteType(List<Integer> b){
b.add(1);
System.out.println("b hashcode:" + b.hashCode());
}
public static void main(String[] args) {
List<Integer> quoteParam = new ArrayList<>();
ParamsTrans.QuoteType(quoteParam);
System.out.println(quoteParam.toString());
System.out.println("quoteParam hashcode:" + quoteParam.hashCode());
}
}
// 結果:
// b hashcode:32
// [1]
// quoteParam hashcode:32
結果分析:引用資料型別quoteParam初始值為空,在函式中新增元素,輸出值為[1],說明函式內的操作已生效。由變數hash值可以看出,函式內與函式外為同一變數。
3、包裝資料型別傳值
在Java中,有一些對基本資料型別進行包裝的型別,在引數傳值時比較容易混淆,如:String、Integer、Double等。
-
String型別
public class ParamsTrans { /** * Sting型別傳值 * @param c */ private static void StringType(String c){ c = "b"; System.out.println("c hashcode:" + c.hashCode()); } public static void main(String[] args) { String stringParam = "a"; StringType(stringParam); System.out.println(stringParam); System.out.println("stringParam hashcode:" + stringParam.hashCode()); } } // 結果: // c hashcode:98 // a // stringParam hashcode:97
結果分析:由程式碼執行結果可以看出,String型別雖然是引用變數,但是在函式中對其進行修改的操作並未生效,且函式內與函式外的變數也並不是同一個變數。這不符合上述引用資料型別的規律,由String型別原始碼可知,String中字串實際是用char[]陣列進行儲存的,相當於是char[]的包裝類。因此,在引數傳遞時,是對引數進行了拷貝。
-
Integer型別及包裝型別
根據上述對String型別的分析,檢視Integer類原始碼,對Integer類進行賦值實際是對int型別進行操作。綜上所述,在函式引數傳值時,Integer與String具有相同特性。再推廣至包裝型別,所有包裝型別均具有此特性。