這個問題一直困擾着初級程序員,如果這個問題不能解決,以後在做程序的時候可能會收到影響。
其實這個問題是從C++中的傳值和傳指針中遺留來的,我們知道java中的引用其實是類似於C++中的指針,都是指向它所表示的對象,只不過java對指針有進行了一次封裝,這樣比直接拿到對象的指針操作起來更安全了,其實本質上都是指針。
對基本類型的變量,沒有任何人去爭論,都知道它是傳值的。但是對於指針類型就迷糊了,因爲在傳遞指針的時候,如果在函數中用指針對原來的對象進行了修改,這真的就會影響到它所指向的對象,也就是這麼一個副作用,讓我們覺得它不同於基本類型的值傳遞,也就有了引用傳遞一說。
但是仔細研究一下,引用傳遞其實也是值傳遞,它傳遞的是引用的值,而不是引用指向的對象的值。傳遞的過程是這樣進行的,當調用一個方法並向方法傳遞一個引用參數是,會先把原來的引用複製一份然後傳遞給這個方法,你沒有看錯,這就像基本類型傳遞一樣,先將基本類型的值複製一份然後傳遞給方法,那麼我們在方法中對這個引用值做的任何修改都不會對原來這個引用的原版造成任何影響。我們可以用下面這個交換兩個引用值的方法來說明這一點。
public class Test{
public static void main(String[] args){
People xiaoming = new People(21, "xiaoming");
People dazhang= new People(34, "dazhang");
System.out.println("交換前====================");
System.out.println(xiaoming);
System.out.println(dazhang);
swap(xiaoming, xiaozhang);
System.out.println("交換後====================");
System.out.println(xiaoming);
System.out.println(dazhang);
}
public static void swap(People a, People b){
People temp;
temp =a; a = b; b = temp;
}
class People{
int age;
String name;
public People(int age, String name){
this.age = age; this name = name;
}
public String toString(){
return name + ":" + age;
}
}
}
如果我們對傳進來的引用副本指向的對象做了修改,那引用原版指向的對象相應的也發生了改變,這也可以通過下面一個程序來驗證。
public class Test{
public static void main(String[] args){
People xiaoming = new People(21, "xiaoming");
System.out.println("Before change==================");
System.out.println(xiaoming.name + ":" + xiaoming.age);
change(a);
System.out.println("After change==================");
System.out.println(xiaoming.name + ":" + xiaoming.age);
}
public static void changeAge(People a){
a.age = 108;
}
class Peopel{
int age;
int name;
public People(int age, int name){
this.age = age; this.name = name;
}
}
}