java到底是引用傳遞還是值傳遞?
今天我們來講講一個在學習中容易誤解的問題,面試中也偶爾問到,java方法調用時到底是值傳遞還是引用傳遞?
首先,請大家來做一個判斷題,下面的3個問題是否描述正確
1. java基本數據類型傳遞是值傳遞,引用數據類型是引用傳遞
2. java都是引用傳遞
3. 方法調用時傳的是數據值就是指傳遞,傳的是地址就是引用傳遞
我們暫且不直說上面3個問題的正確性,下面,我們通過幾個測試案例來測試一下參數傳遞
1. 基本數據類型當作參數
public class test1 { public static void main(String[] args) throws Exception { int a = 10; change(a); System.out.println("a = " + a); } public static void change(int s) { s = 20; System.out.println("s = " + s); } }
運行結果: 方法執行後,沒有改變原有a的值
s = 20
a = 10
2. 引用類型當作參數
public class Student { private String name; //姓名 Student(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; }} public class Test1{
public static void main(String[] args) throws Exception {
Student s = new Student("haly");
change(s);
System.out.println("s = " + s.getName());
}
public static void change(Student x) {
x.setName("wuwu");
}
}
運行結果: 方法執行後,改變了原來s的值
x = wuwu
s = wuwu
看到這裏,很多同學就覺得問題1答案是正確的, java基本數據類型傳遞是值傳遞,引用數據類型是引用傳遞,但是真的是這樣嗎?
這裏我可以提前透露下答案,上面這個測試之所以改變了原來實參s裏面的值,是因為我們傳遞到方法的都是實參對象的一個拷貝,x對象是s對象引用的一個拷貝,
所以x和s都是指向同一塊內存地址,改變x裏面的值,相當於改變s的值,因為傳的是對象引用的拷貝,而不是對象引用本身,所以是值傳遞。
如果不好理解,我給大家舉個例子:
我有一輛車,我自己有一把車鑰匙,有一天我的女朋友想要開車,我就配制了一把車鑰匙給她,這時候,相當於方法調用,傳遞了一把鑰匙的拷貝給她。
她在鑰匙上刻字,對我的鑰匙是沒有影響的,但是她拿鑰匙打開車,將我的車坐墊換了,我開這輛車的時候,車坐墊的確是換掉了,這是同一個道理。
如果還不清楚,我用兩張圖,分別表示案例1和案例2的值傳遞:
案例1 案例2
如果大家還不好理解,下面我就寫一個案例3,讓大家更加清晰的看出,java是值傳遞
3. 引用類型當作參數
public class Test1 { public static void main(String[] args) throws Exception { Student s1 = new Student("小張"); Student s2 = new Student("小李"); Test1.swap(s1, s2); System.out.println("s1:" + s1.getName() + ",s2:" + s2.getName()); } public static void swap(Student x, Student y) { Student temp = x; x = y; y = temp; System.out.println("x:" + x.getName() + ",y:" + y.getName()); } }
運行結果:
x:小李,y:小張
s1:小張,s2:小李
通過測試3的代碼,我們可以看出,在方法中交換了兩個參數的值,但是原來的值並沒有交換,如果是引用傳遞的話,我們操作的都是實參本身的引用,按理也會交換的。
下面,我們通過一個圖在仔細思考一下答案:我們交換了x和y對象的引用,對原來的s1和s2並沒有影響。
通過以上代碼及圖描述,我們可以得出如下2個結論:
1. 如果我們傳遞的實參是對象引用的拷貝,就是值傳遞,如果我們傳遞的實參是引用本身,就是引用傳遞。
2. 在java中,不管基本數據類型,還是引用類型,都是值傳遞。
如有不正確的地方,歡迎大家批評指出,一起進步~~
java到底是引用傳遞還是值傳遞?