1. 程式人生 > >Java函式中傳值與傳引用的區別

Java函式中傳值與傳引用的區別

1、對於基本資料型別,傳遞到函式中的是源變數的值

看下面例子:

public class Value_Index {
	public static void main(String[] args){
		int i = 100;
		method(i);
		System.out.println("method()中   i = "+method(i));
		System.out.println("i = " + i);
	}
	private static int method(int i) {
		i = i + 100;
		return i;
	}
}

上例結果為:

method()中   i = 200
i = 100


從例子中可以看出,雖然函式中返回的 i = 200,但是最初宣告的 i 的值還是沒變,等於100。所以對於基本型別只是把變數的值傳遞給函式,源變數的值不會因為函式裡面的運算而改變。

2、對於物件型別,可以理解為傳遞到函式中的為物件的引用

看下面的例子:

public class Test2 {
	public static void main(String[] args){
		StringBuilder a = new StringBuilder("AAA");
		StringBuilder b = new StringBuilder("BBB");
		String c = new String("CCC");
		method(a, b);
		string_method(c);
		System.out.println(a);
		System.out.println(b);
		System.out.println(c);
	}
	private static void method(StringBuilder x, StringBuilder y) {
		x = x.append(y);
		x = y;
		y = x;
	}
	private static void string_method(String z) {
		z.replace('C', 'D');
	}
}


上例的執行結果為:

AAABBB
BBB
CCC

從中可以看出,a的值發生了變化,但是b和c的值卻沒有發生變化。看下圖有助於理解其中的變化


這是因為往method方法中,傳遞了a和b的引用,所以最初x和y分別引用"AAA"和"BBB",經過x.append(y)方法,這裡會在它引用的值上進行修改,所以此時原來的"AAA",變為了"AAABBB","BBB"的值並沒有變。接下來 x = y,是將x指向y現在指向的地址,即"BBB",此時 y = x,即將y指向x所指向的地址,還是"BBB"。但是method方法裡面的這些修改並沒有影響到a和b所指向的地址,但由於a原先指向的"AAA"已經變為"AAABBB",所以打印出來a的值發生了變化,但是b所指向的"BBB"沒有變化,所以列印的b的值沒有改變。

最後看看String c,如果按上面的分析,c的值應該會發生改變,但是由於String是不能變化的,執行string_method方法中 replace()方法並不是在c所指向的"CCC",上做操作,而是又重新new了一個String物件"CCC",所以最終結果是c的值不會發生變化。

總結:

  1. 基本資料型別是傳值到函式中,函式中的運算並不會改變源變數的值;
  2. 物件資料型別是傳遞的引用,如果函式中的操作是在源引用上修改物件值,則最終源變數會發生變化,如例2中的StringBuilder a,但是如果函式中的操作不是在源引用上修改物件值,則最終源物件不會發生改變,如例2中的String c;