java中函數是值傳遞還是引用傳遞?
相信有些同學跟我一樣,曾經對這個問題很疑惑。在網上也看了一些別人說的觀點,評論不一。有說有值傳遞和引用傳遞兩種,也有說只有值傳遞的,這里只說下個人見解
先看一個例子
public class Test1 {
public static void main(String[] args) {
int a = 10;
changeNum(a);
System.out.println("main a=" + a);
}
static void changeNum(int a) {
a = 100;
System.out.println("changeNum a=" + a);
}
}
結果:
changeNum a=100
main a=10
說明對于基本的數值類型其實傳遞的是一份數值的拷貝,傳入函數之后跟原來的值就沒有關系了,在函數中改變這個數的值也不會影響到原來的值。
再看一個例子
public class P {
String name = "P";
public P(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class Test {
static P p1 = new P("p1");
public static void main(String[] args) {
P p = new P("P");
System.out.println("before change p:" + p.toString);
changeObj(p);
System.out.println("after change p:" + p.toString());
}
static void changeObj(P p) {
p = new P("pp");
System.out.println("change p:" + p.toString());
//p = p1;
//System.out.println(p.toString());
}
}
這個例子中的運行結果會是什么呢?
在這個例子中傳入的是一個對象類型的數據。
我們先來猜想一下:如果傳入的是一個對象的引用,在函數中改變了這個引用所指向的對象,那么外部的引用"p"應該是指向了新創建的P("pp")的對象才對
所以猜想的結果是:
before change p:P
change p:pp
after change p:pp
那讓我們來實際運行一下看看結果,實際的結果是:
before change p:P
change p:pp
after change p:P
想猜想的不一樣!!!
這就讓我們很疑惑了,為什么函數沒有改變引用所指向對象呢?
其實是這樣的,首先要理解“=”賦值操作的意義,
對于基本類型來說“=”賦值操作是直接改變內存地址上的值,
而對引用類型來說“=”賦值其實是改變引用變量所指向的內存地址。
賦值操作后
引用的賦值并沒有對原來的對象造成影響,"hello"對象仍然是存在的,只是str又指向了新的"world"對象
理解了賦值操作后,現在來說下函數的參數傳遞
函數的參數實際上就是函數內部的一個局部變量,從外部傳值給這個參數實際上就是一個賦值的過程。
來看看第一個例子,傳一個定義一個int類型名稱為a的形式參數,其實完全可以把名稱改為b
然后把外部變量a的值傳遞給函數的變量,就是賦值。基本類型的賦值就是把外部a變量的10賦值給函數變量a,所以這其實是兩個變量,兩者之間沒有任何關系,
所以對函數內部變量的改變也不會對外部的變量造成影響。
再來說下引用類型的傳遞,其實是一個道理。
在傳遞的時候是把一個對象的內存地址賦值給函數內部的引用類型的局部變量
如上圖所示,兩個變量是指向同一個對象的。
在第二個例子中,我們在函數內部新創建了一個對象,并重新賦值給內部變量p,其實是改變了內部變量的引用所指向的對象,如下圖所示
所以對外部的p變量是沒有影響的。
總結:
函數參數傳遞其實是一個賦值的過程,基本類型傳遞的是數值,引用類型傳遞的引用對象的內存地址。
另外一點要特別注意,函數的參數其實是函數內部的局部變量。不要跟外部變量混淆
來自:http://www.cnblogs.com/taixuyingcai/p/6373423.html