天天看點

java基礎:所有參數皆是按值參數

c#中對于參數的傳遞,有二種處理方式,預設情況下:值類型的參數,按值傳遞(即:方法體内的參數是原值的副本);引用類型的參數,"加ref關鍵字後“,按引用傳遞(即:方法體内的參數,是對象的指針引用,在方法體内修改了對象的屬性,方法調用完成後,這種變化也會保持下去).

java雖然也是OO語言,但是這一點有很大不同,不管是“值”類型的簡單參數(比如:int),還是“引用”類型的對象參數(比如:Object),參數永遠是按值傳遞(參數永遠是原值的副本)。隻不過,對于int型的簡單參數,比如:5,副本也是5,相當于在記憶體又開辟一塊空間,存儲5這個值,但這二個5完全不相關聯。而對于對象參數(比如:Object),參數副本應了解成對象指針引用“位址值”的副本,比如:原Object對象在記憶體中的指針位址為OX0001,則參數為OX0001的另一個副本,因為這二個位址值相同,是以在大多數情況下,方法體内,通過指針位址定位到的對象是同一個,即:方法體内修改對象的屬性,該對象就被永遠修改了,即使方法調用完成,這種修改的結果也會永遠儲存下去。這給很多java初學者造成java中參數有按引用傳遞的錯覺。

看下面的示例:

先定義一個測試用的Person類

java基礎:所有參數皆是按值參數
java基礎:所有參數皆是按值參數

View Code

然後來一個單元測試

java基礎:所有參數皆是按值參數
java基礎:所有參數皆是按值參數

運作結果:

name:aaa

name:xxx

java基礎:所有參數皆是按值參數

如上圖所示,這種情況很好了解,p1,p因為值相同,是以根據這個位址值,尋址找到的對象是同一個,改p.name值與改p1.name沒什麼分别

再來一個版本:

java基礎:所有參數皆是按值參數
java基礎:所有參數皆是按值參數

name:yyy

java基礎:所有參數皆是按值參數

如上圖,剛開始P1,P值相同,但是在ChangePerson2内部,又new了一個Person的新執行個體:newPerson,修改newPerson.Name,并不會影響P1和P,在最後,将newPerson指派給p,注意:p隻是p1的位址值副本,是以雖然p與newPerson最終指向一樣了,但是并不會影響原值p1,是以方法調用完成後,p1.name還是原來的值