java 是值傳遞(pass by value),還是引用傳遞(pass by reference)?
答案是:值傳遞(pass by value)
先說(shuō)一下值傳遞和引用傳遞的概念和區(qū)別吧
值傳遞:是指在調(diào)用函數(shù)時(shí),將原始參對(duì)象復(fù)制一份作為實(shí)參傳給形參,當(dāng)在函數(shù)中對(duì)參數(shù)進(jìn)行修改時(shí)鸭限,不會(huì)影響到實(shí)際參數(shù)排抬。
引用傳遞:是指在調(diào)用函數(shù)時(shí),將原始對(duì)象直接作為實(shí)參傳給形參连舍,一旦在函數(shù)中對(duì)其進(jìn)行修改没陡,將會(huì)影響實(shí)際參數(shù)。
其主要區(qū)別是:
接下來(lái)讓我們看一段例子:
public static void main(String[] args) {
int i = 2;
modify(i);
System.out.println("print in main : i = " + i);
}
public static void modify(int j) {
j = 4;
System.out.println("print in modify : j = " + j);
}
打印結(jié)果如下:
print in modify : j = 4
print in main : i = 2
從打印結(jié)果可以看出索赏,當(dāng)我們修改了形參j時(shí)诗鸭,對(duì)于實(shí)際參數(shù)i,并沒有發(fā)生改變参滴,這替我們證明了强岸,對(duì)于基本數(shù)據(jù)類型來(lái)說(shuō),傳遞的是值
接下來(lái)讓我們看看引用數(shù)據(jù)類型
public static void main(String[] args) {
A a = new A();
a.setName("Martina");
modify(a);
System.out.println("print in main : a.name = " + a.getName());
}
public static void modify(A b) {
b.setName("Leon");
System.out.println("print in modify : b.name = " + b.getName());
}
打印結(jié)果如下:
print in modify : b.name = Leon
print in main : a.name = Leon
我們發(fā)現(xiàn)砾赔,實(shí)際參數(shù)a的內(nèi)容隨著函數(shù)里的修改也發(fā)生了改變蝌箍,這是不是說(shuō)明對(duì)于引用類型,是引用傳遞呢暴心,不妓盲,希望你們不要產(chǎn)生這樣的誤解。對(duì)于引用類型专普,依舊是值傳遞悯衬,先看看下面一段代碼。
public static void main(String[] args) {
A a = new A();
a.setName("Martina");
modify(a);
System.out.println("print in main : a.name = " + a.getName());
}
public static void modify(A b) {
b = new A();
b.setName("Leon");
System.out.println("print in modify : b.name = " + b.getName());
}
看看打印結(jié)果:
print in modify : b.name = Leon
print in main : a.name = Martina
這個(gè)時(shí)候我們的原始對(duì)象并沒有發(fā)生改變檀夹,而這一段與上一段的區(qū)別在于:
b = new A();
如果是引用傳遞筋粗,那么我們的原始參數(shù)a應(yīng)該還是會(huì)發(fā)生影響的策橘,所以還是先讓我們看一下這兩個(gè)例子到底發(fā)生了什么:
當(dāng)我們?cè)趥鬟f參數(shù)時(shí),將原始對(duì)象的地址傳給了形參娜亿,在函數(shù)中丽已,對(duì)形參的內(nèi)容進(jìn)行了改變,也就是买决,改變了原始對(duì)象的內(nèi)容沛婴。
而在 b=new A(); 的時(shí)候,改變了形參的地址督赤,對(duì)原始對(duì)象的內(nèi)容沒有進(jìn)行影響嘁灯。故而我們可以判斷出,這并不是引用傳遞躲舌,如果是旁仿,在 b=newA(); 的時(shí)候,a的地址也應(yīng)該發(fā)生改變孽糖,事實(shí)并沒有枯冈,故而證明java就是值傳遞。
還有一個(gè)比較生動(dòng)的例子來(lái)描述值傳遞和引用傳遞办悟。
小劇場(chǎng):
小明家有一個(gè)電視尘奏,有一天,他的合租室友小吳想看電視了病蛉,小明就去店里給他配了一個(gè)遙控器炫加。這一天,小明和小吳铺然,在家里看電視俗孝,小吳在小明去倒水的時(shí)候說(shuō),我們看“CCTV”吧魄健,于是他用自己的遙控器換了臺(tái)赋铝,等小明回來(lái),他看到的就是CCTV正在播放的電影頻道沽瘦。忽然小吳不小心把水灑在了自己的遙控器上革骨,于是他就要用小明的遙控器換臺(tái)了,他一不小心將手里的番茄醬沾在了小明的遙控器上析恋,等小明拿到遙控器的時(shí)候良哲,沾了一手的番茄醬。
你有一個(gè)遙控器助隧,專門操作這個(gè)電視筑凫,值傳遞就是,你復(fù)制了一個(gè)遙控器給了別人,他也可以操作這個(gè)電視巍实,當(dāng)他換臺(tái)了滓技,也就意味著這個(gè)電視機(jī)的內(nèi)容發(fā)生了改變,但是你的遙控器他卻沒有改變的權(quán)利蔫浆,引用傳遞就是,你把自己的遙控器給了別人姐叁,別人拿著你的遙控器對(duì)電視機(jī)進(jìn)行操作瓦盛,他還可以對(duì)你的遙控器進(jìn)行操作,這便是引用傳遞外潜。故而由電視的內(nèi)容是否改變來(lái)判斷這個(gè)問題是不太適合的原环,咱也不要糾結(jié)為啥內(nèi)容發(fā)生了改變,咱給的是遙控器啊处窥,看的是遙控器有沒有變嘱吗。b=new A();這個(gè)操作則是給了他另一個(gè)電視的遙控器。
總結(jié)
讓我們?cè)賮?lái)梳理清楚滔驾,java是值傳遞這個(gè)概念谒麦,我們?cè)谏厦嬉呀?jīng)給出了值傳遞和引用傳遞之前的區(qū)別:是否復(fù)制副本,是否會(huì)影響到原始對(duì)象哆致。根據(jù)上面的例子绕德,我們可以總結(jié):對(duì)于基本數(shù)據(jù)類型,傳遞的是原始數(shù)據(jù)的值的副本摊阀,對(duì)于引用數(shù)據(jù)類型耻蛇,傳遞的是原始數(shù)據(jù)地址值的副本。
看看人外國(guó)大佬的回答:
所以胞此,別問臣咖,問,就是值傳遞J!6嵘摺!