概述
我以前也以為JAVA中有值傳遞和引用傳遞,但是在后來(lái)的學(xué)習(xí)中我漸漸意識(shí)到這是個(gè)錯(cuò)誤的想法,現(xiàn)在來(lái)總結(jié)一下
大家常見的錯(cuò)誤想法大概有:
- 值傳遞和引用傳遞,區(qū)分的條件是傳遞的內(nèi)容,如果是個(gè)值,就是值傳遞。如果是個(gè)引用,就是引用傳遞。
- 傳遞的參數(shù)如果是普通類型,那就是值傳遞,如果是對(duì)象,那就是引用傳遞。
我們來(lái)看一下值傳遞和引用傳遞的定義:
- 值傳遞(pass by value)是指在調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)復(fù)制一份傳遞到函數(shù)中,這樣在函數(shù)中如果對(duì)參數(shù)進(jìn)行修改,將不會(huì)影響到實(shí)際參數(shù)。
- 引用傳遞(pass by reference)是指在調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)的地址直接傳遞到函數(shù)中,那么在函數(shù)中對(duì)參數(shù)所進(jìn)行的修改,將影響到實(shí)際參數(shù)。
我們來(lái)看幾個(gè)例子
public static void main(String[] args){
int a = 10;
change(a);
system.out.println("a=" + a);
public void change(int b){
b = 20;
system.out.println("b=" + b);
}
}
輸出
a = 10
b = 20
- 第二個(gè)例子
public static void main(String[] args){
User user = new User();
user.setName("aaa")
change(user);
system.out.println("name = " + user.getName());
public void change(User user){
user.setName("bbb");
system.out.println("name = " + user.getName());
}
}
輸出
name = bbb
name = bbb
- 第一個(gè)例子很好理解,基礎(chǔ)類型放在棧中,實(shí)參被復(fù)制一份到形參中,為值傳遞,實(shí)參和形參是兩個(gè)獨(dú)立的值,修改其中一個(gè)不會(huì)影響其他一個(gè)
- 第二個(gè)例子就會(huì)誤認(rèn)為是引用傳遞,對(duì)象存放在堆中,形參和實(shí)參均指向堆中的同一個(gè)
user對(duì)象,修改對(duì)象中內(nèi)容就會(huì)引起變化,那么問(wèn)題出在哪呢?
- 它傳遞的是引用么?不是,它傳遞的是引用的值,也就是引用的值傳遞,怎么理解這句話,我們來(lái)舉個(gè)例子:
- 假如我們有只有一把鑰匙能打開鎖,我們將這把鑰匙借給了朋友,,他打開了鎖,使得鎖的狀態(tài)發(fā)生了變化,然后朋友在鑰匙上刻了名字,當(dāng)還給我們的時(shí)候鑰匙上仍然有名字,因?yàn)檫@是同一把鑰匙,這是引用傳遞,本質(zhì)是同一個(gè)引用,只是將引用傳遞給了別人
- 但是如果我們是復(fù)制了一把鑰匙給朋友,他仍然可以將鎖打開,使得鎖狀態(tài)發(fā)送變化,但是他在鑰匙上刻名字并不會(huì)影響到我們的鑰匙,這是兩把鑰匙,這就是引用的值傳遞,復(fù)制一個(gè)引用給別人