Java引數傳遞是傳值還是傳引用?
參考:http://ifeve.com/stackoverflow-reference-or-value/
http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
在Java的規範裡說明了在Java中一切引數都是按值傳遞的,根本就沒有引用傳遞這一說。
理解這個概念的關鍵是要明白:
Dog myDog;
這裡宣告的並不是一個Dog物件,而是一個指向Dog物件的指標。
這是什麼意思呢,就是當你執行:
Dog myDog = new Dog("Rover");
foo(myDog);
本質上是你把建立好的Dog物件的地址傳遞給foo方法。(我說的‘本質上’其實是因為Java中的指標並不是直接的地址,不過可以簡單的理解成這樣)。
假設Dog物件在記憶體中的地址是42。那我們就是把42這個值傳遞給了foo方法。
public void foo(Dog someDog) {
someDog.setName("Max"); // AAA
someDog = new Dog("Fifi"); // BBB
someDog.setName("Rowlf"); // CCC
}
讓我們來看看執行的時候會發生些什麼。
- someDog的值設定為42。
- 在AAA行
a.someDog指向一個記憶體地址為42的Dog物件。
b.把Dog(記憶體地址為42)物件的name屬性改為Max。 - 在BBB行
a.一個新的Dog物件被建立,我們假設它的記憶體地址是74。
b.把這個74的記憶體地址值賦給someDog。 - 在CCC行
a.someDog指向一個記憶體地址為74的Dog物件。
b.把Dog(記憶體地址為74)物件的name屬性改為Rowlf。 - 方法執行完畢。
現在讓我們來想想在這個方法外面發生了什麼:
myDog改變了嗎?
這個問題的關鍵在於:
要明確myDog是一個指標,而不是一個實際的Dog物件。所以答案是它沒有改變,myDog的值還是42;它指向的還是最開始的那個Dog物件(雖然在foo方法中的AAA行把它指向物件的name屬性改成了Max,但是它指向的還是那個最初的Dog物件)。
這驗證了改變所指物件的屬性,但沒有改變其指向。
Java的執行機制跟C很像。你可以給一個指標賦值,然後把這個指標傳遞給一個方法,之後在這個方法中你可以改變這個指標指向物件的資料,但是你不能改變這個指標的指向。
在C++,Ada,Pascal以及其他支援引用傳遞的語言中你可以直接改變傳遞的引數。如果Java是引用傳遞的話,那麼在執行上面定義的foo方法的BBB行的時候someDog的指向就會被改變。
Let me explain this through an example:
public class Main{
public static void main(String[] args){
Foo f = new Foo("f");
changeReference(f); // It won't change the reference!
modifyReference(f); // It will modify the object that the reference variable "f" refers to!
}
public static void changeReference(Foo a){
Foo b = new Foo("b");
a = b;
}
public static void modifyReference(Foo c){
c.setAttribute("c");
}
}
I will explain this in steps:
1.Declaring a reference named f of type Foo and assign it to a new object of type Foo with an attribute "f".
Foo f = new Foo("f");
2.From the method side, a reference of type Foo with a name a is declared and it's initially assigned to null.
public static void changeReference(Foo a)
3.As you call the method changeReference, the reference a will be assigned to the object which is passed as an argument.
changeReference(f);
4.Declaring a reference named b of type Foo and assign it to a new object of type Foo with an attribute "b".
Foo b = new Foo("b");
5.a = b is re-assigning the reference a NOT f to the object whose its attribute is "b".
6.As you call modifyReference(Foo c) method, a reference c is created and assigned to the object with attribute "f".
7.c.setAttribute("c"); will change the attribute of the object that reference c points to it, and it's same object that reference f points to it.
相關文章
- Java - 是值傳遞還是引用傳遞Java
- Go語言引數傳遞是傳值?還是傳引用 ?Go
- Go語言引數傳遞是傳值還是傳引用Go
- 解惑4:java是值傳遞還是引用傳遞Java
- go語言引數傳遞到底是傳值還是傳引用Go
- 面試官問:Go 中的引數傳遞是值傳遞還是引用傳遞?面試Go
- JS是按值傳遞還是按引用傳遞?JS
- Java 是傳值還是傳引用 (轉)Java
- Python 函式中,引數是傳值,還是傳引用?Python函式
- 面試官:兄弟,說說Java到底是值傳遞還是引用傳遞面試Java
- 偽命題:Java傳遞的值還是引用?Java
- 搗漿糊的老話題:Java是按值傳遞還是按引用傳遞Java
- 引數傳遞方式必須是const引用傳遞
- java經典問題:傳值還是傳引用(轉)Java
- 關於String是值傳遞還是引用傳遞,talk is cheap, just show codes
- js中函式引數值傳遞和引用傳遞JS函式
- Python的函式引數傳遞:傳值?引用?Python函式
- GO中的函式設計時候,引數傳遞選擇傳遞值還是傳遞指標?Go函式指標
- 你會swap嗎,按值傳遞還是按引用?
- Java中的值傳遞和引用傳遞Java
- Python引數傳遞,既不是傳值也不是傳引用Python
- 值傳遞和引用傳遞
- 值傳遞與引用傳遞
- 188W+程式設計師關注過的問題:Java到底是值傳遞還是引用傳遞?程式設計師Java
- js函式引數值傳遞和引用傳遞簡單介紹JS函式
- java方法中只有值傳遞,沒有引用傳遞Java
- JavaScript的值傳遞和引用傳遞JavaScript
- 快速搞懂值傳遞與引用傳遞
- JS的方法引數傳遞(按值傳遞)JS
- chan中傳遞map資料,傳遞的是引用
- Java 從陣列來看值傳遞和引用傳遞Java陣列
- ABAP 方法呼叫的引數傳遞裡,透過引用傳遞的方式,能修改原始引數值嗎?
- golang工作筆記(二)值傳遞與引用傳遞Golang筆記
- 關於值傳遞和引用傳遞的解釋
- C#引數傳遞之值引數C#
- 獲取url傳遞傳遞的某個引數的值
- JAVA值傳參和引用傳參Java
- js中 函式引數的 傳值/傳引用 問題JS函式