1. 程式人生 > >java到底是引用傳遞還是值傳遞?

java到底是引用傳遞還是值傳遞?

內存 引用數據類型 rgs 傳遞 調用 對象引用 get 參數 案例

今天我們來講講一個在學習中容易誤解的問題,面試中也偶爾問到,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");

System.out.println("x = " + x.getName());
}

}

運行結果: 方法執行後,改變了原來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到底是引用傳遞還是值傳遞?