原文地址:http://blog.csdn.net/whmii/article/details/3363667
變量賦值和參數傳遞是java中兩個容易讓人迷惑的問題。
對於原始類型(primitives type),java采用值傳遞,這很明顯。然而,當傳遞的參數類型是對象時,或者兩個對象的變量進行賦值時,問題就有些復雜,很多初學者對此感到迷惑。
實際上,當賦值或者傳遞參數的時候,Java采取的都是一種值傳遞。
在下面的代碼中,
- class A{
- int i=2;
- }
- class B{
- static void change(A a){
- a.i=31;
- }
- public static void main(String[] arguments){
- A a1=new A();
- A a2=new A();
- change(a1);
- System.out.println("a1: "+a1.i+"/na2: "+a2.i); // a1=31,a2=2;
- a1=a2;
- System.out.println("a1: "+a1.i+"/na2: "+a2.i); // a1=2,a2=2;
- }
- }
當執行change(a1)時,JVM將a1復制一份傳遞給A的靜態函數change(A a)中的參數a,注意這里a1和a都是對象的引用,而不是對象本身。所以,傳遞的是對象引用的復制品。從而a1和a變成同一個對象的兩個不同引用。因此,通過a1對對象的改變,和通過a對對象的改變,具有同樣的效果。打個比方,有一道帶有復雜無比的鎖的門(對象),這扇門有一把鑰匙(a1)。現在,另外一個人會開此門(方法change()的定義),他有一把想象中的鑰匙(形參),但他沒有事實上的鑰匙。當此人需要開此門時,怎么辦?他需要一把鑰匙,而主人傳給他的確實是一把鑰匙,只不過這把鑰匙是主人原先的鑰匙的復制品!而這個復制品顯然也能打開這扇復雜的門。
同樣,對於第13行的
a1=a2;
是這樣進行的:復制前,a1和a2分別是兩個不同對象的引用,當賦值時,a2的值賦給a1,結果a1的值和a2的值相等,a1變成a2所引用的對象的另一個引用,即a1和a2變成同一個對象的引用,而這個對象是原先a2引用的對象。原先a1引用的對象則因為失去了所有的引用而被垃圾收集器處理掉!