1. 程式人生 > >Java中的值傳遞與“引用傳遞”

Java中的值傳遞與“引用傳遞”

首先解釋下值傳遞和引用傳遞:

值傳遞:傳遞的是值的拷貝,就是在方法呼叫的時候,實參是將自己的一份拷貝傳遞給形參,也就是說傳遞後實參與形參就互不相關了。在方法內,對該引數值的修改不影響原來實參。

引用傳遞:指的是在方法呼叫時,引數是按引用進行傳遞,也就是實參的記憶體空間地址。此時在方法內對該引數值的修改會影響到實參。

然後拋個問題:

Java中物件作為引數傳遞給一個方法,到底是值傳遞還是引用傳遞?

答案:值傳遞。 Java中只有值傳遞,沒有引用傳遞。

那疑問就來了:在Java中,經常會將一個物件作為引數傳遞給一個方法,而在方法內部對形參的修改是會影響到該物件的。這麼來看,這種引數傳遞方式不就是引用傳遞嗎?

其實不然,下面我們來一步步看下為什麼這種傳遞方式並不是引用傳遞。

1.首先看下值傳遞的一個例子:

public class TempTest {
	private void test (int a) {
		a = 5;
		System.out.println("test方法中的a=" + a);
	}
	public static void main (String[] args) {
		TempTest tt = new TempTest();
		int a = 3;
		tt.test(a);
		System.out.println("main方法中的a=" + a);
	}
}
輸出結果為:

test方法中的a=5

main方法中的a=3

這個很好理解,test方法中的a是一份拷貝,想怎麼改怎麼改,不影響main方法中的a。

2.然後看下一個例子:

public class TempTest {
	private void test (StringBuffer s) {
		//s = new StringBuffer("good");
		s.append("boy");
	}
	public static void main (String[] args) {
		TempTest tt = new TempTest();
		StringBuffer sb = new StringBuffer("bad ");
		tt.test(sb);
		System.out.println(sb);
	}
}
輸出結果為:

bad boy

這個結果讓人覺得,這不就是引用傳遞嗎?

3.現在我們把test方法中第一行的註釋放開,執行一下,結果為:

bad

這還是引用傳遞嗎?顯然不是。在test方法中對形參s的引用地址進行了修改,如果是引用傳遞,此時對形參s的改變就是對實參sb的操作,那麼輸出應該為“good boy”。但實際上並不是這樣,這說明實參sb指向的還是原來的物件,而形參s指向的才是新建立的物件,這也就說明了Java中的物件傳遞也是值傳遞。

下面用圖的形式,更加直觀的解釋下引數到底是怎麼傳遞的:

結合上圖和例子,應該就能理解Java中的引數傳遞了。

最後總結一句:

Java的引數傳遞,不管是原始型別還是引用型別,傳遞的都是副本(實參的拷貝),一個是值的副本,一個是引用的副本。