回覆列表
  • 1 # 數碼視界大爆炸

    值傳遞(pass by value)是指在呼叫函式時將實際引數複製一份傳遞到函式中,這樣在函式中如果對引數進行修改,將不會影響到實際引數。我們來看下面一張圖,看一下整個過程中發生了什麼,為啥Java中只有值傳遞。

    稍微解釋下這張圖,當我們在main中建立一個User物件的時候,在堆中開闢一塊記憶體,其中儲存了name和gender等資料。然後hollis持有該記憶體的地址0x123456(圖1)。

    當嘗試呼叫pass方法,並且hollis作為實際引數傳遞給形式引數user的時候,會把這個地址0x123456交給user,這時,user也指向了這個地址(圖2)。

    然後在pass方法內對引數進行修改的時候,即user = new User();,會重新開闢一塊0X456789的記憶體,賦值給user。後面對user的任何修改都不會改變記憶體0X123456的內容(圖3)。

    上面這種傳遞是什麼傳遞?肯定不是引用傳遞,如果是引用傳遞的話,在執行user = new User();的時候,實際引數的引用也應該改為指向0X456789,但是實際上並沒有。引用傳遞(pass by reference)是指在呼叫函式時將實際引數的地址直接傳遞到函式中,那麼在函式中對引數所進行的修改,將影響到實際引數。

    所以,值傳遞和引用傳遞的區別並不是傳遞的內容。而是實參到底有沒有被複制一份給形參。在判斷實參內容有沒有受影響的時候,要看傳的的是什麼,如果你傳遞的是個地址,那麼就看這個地址的變化會不會有影響,而不是看地址指向的物件的變化。就像鑰匙和房子的關係。那麼,既然這樣,為啥上面同樣是傳遞物件,傳遞的String物件和User物件的表現結果不一樣呢?我們在pass方法中使用name = "hollischuang";試著去更改name的值,陰差陽錯的直接改變了name的引用的地址。因為這段程式碼,會new一個String,再把引用交給name。而原來的那個”Hollis”字串還是由實參持有著的,所以,並沒有修改到實際引數的值。

    所以說,Java中其實還是值傳遞的,只不過對於物件引數,值的內容是物件的引用。

  • 2 # 嘉靖不上朝

    相信我,目前來說,只要是程式語言,值傳遞(基本資料型別)、引用傳遞(物件型別)都存在的,不只是有值傳遞。

  • 3 # 程式設計師進軍SJF

    其實傳遞方式有“值傳遞”和 “引用傳遞”

    先看一下他兩定義

    值傳遞(pass by value)是指在呼叫函式時將實際引數複製一份傳遞到函式中,這樣在函式中如果對引數進行修改,將不

    會影響到實際引數。

    引用傳遞(pass by reference)是指在呼叫函式時將實際引數的地址直接傳遞到函式中,那麼在函式中對引數所進行的修改,將影響到實際引數。

    區別

    值傳遞和引用傳遞的區別並不是傳遞的內容。而是實參到底有沒有被複制一份給形參。

    對於物件引數,值的內容是物件的引用,所以就不是引用傳遞。

    無論是值傳遞還是引用傳遞,其實都是一種求值策略(Evaluation strategy)。在求值策略中,還有一種叫做按共享傳遞(call by sh

    aring)。其實Java中的引數傳遞嚴格意義上說應該是按共享傳遞。

    按共享傳遞,是指在呼叫函式時,傳遞給函式的是實參的地址的複製(如果實參在棧中,則直接複製該值)。在函式內部對引數進行操作時,需要先複製的地址尋找到具體的值,再進行操作。如果該值在棧中,那麼因為是直接複製的值,所以函式內部對引數進行操作不會對外部變數產生影響。如果

    原來複製的是原值在堆中的地址,那麼需要先根據該地址找到堆中對應的位置,再進行操作。因為傳遞的是地址的複製所以函式內對值的操作對外部變數是可見的。

    簡單點說,Java中的傳遞,是值傳遞,而這個值,實際上是物件的引用。

    而按共享傳遞其實只是按值傳遞的一個

    特例罷了。所以我們可以說Java的傳遞是按共享傳遞,或者說Java中的傳遞是值傳遞。

  • 4 # Java實戰技術

    關於這個問題,不同人對它的理解不盡相同。對初學Java的同學來說,可能簡單的認為Java中引數傳遞就是分為值傳遞和引用傳遞,至於為什麼,因為課本上就是這麼說的。對於有些工作年限的程式設計師來說,可能認為如果傳遞的引數型別是普通型別,那麼就是值傳遞,如果引數是物件,那麼就是引用傳遞。還有一些人認為Java中只有值傳遞,就是題主問題中的主題。

    對Java程式語言來說,前兩種理解是錯誤的,Java中只有值傳遞。對於我來說,剛開始也是理解有值傳遞和引用傳遞一說的,但是隨著自己寫程式碼的積累,慢慢發現並不是那麼回事。那為什麼只有值傳遞呢?

    首先,來了解一下什麼是值傳遞,什麼是引用傳遞?

    值傳遞是說在呼叫函式時,將實際引數值複製一份傳遞到被呼叫函式中,在被調函式中修改引數值不會影響原實參值。

    引用傳遞是說在呼叫函式時,將實際引數的地址直接傳遞到被呼叫的函式中,在被調函式中修改引數值會影響原實參值。

    如果傳遞的引數型別是普通基本型別,那麼一定是複製一份實參值傳遞給形參的,但是當引數型別是物件的時候,也是複製的一份引數值傳遞給形參,只不過複製的是物件引用的地址,也就是在記憶體中分配的儲存地址,不是直接傳遞的引用地址。

    此時,可能有人會說那為什麼將一個物件傳到另一個方法中,在這個方法中修改了這個物件的屬性值時,原呼叫方法中的物件屬性值也跟著變了,它不就是引用傳遞嗎?

    其實,這是一個很容易迷惑的點。你仔細看看上面的陳述就會發現,不是這麼回事。將一個物件傳到另一個方法中,傳遞的是什麼?傳遞的是物件引用的地址,這個物件引用的地址在另一個方法中被修改了嗎?原物件引用有受影響嗎?並沒有吧!

    所以,Java中並沒有引用傳遞,只有值傳遞,不要再搞錯了!

  • 5 # AA蘇西老師

    首先,來了解一下什麼是值傳遞,什麼是引用傳遞?

    值傳遞是說在呼叫函式時,將實際引數值複製一份傳遞到被呼叫函式中,在被調函式中修改引數值不會影響原實參值。

    引用傳遞是說在呼叫函式時,將實際引數的地址直接傳遞到被呼叫的函式中,在被調函式中修改引數值會影響原實參值。

    如果傳遞的引數型別是普通基本型別,那麼一定是複製一份實參值傳遞給形參的,但是當引數型別是物件的時候,也是複製的一份引數值傳遞給形參,只不過複製的是物件引用的地址,也就是在記憶體中分配的儲存地址,不是直接傳遞的引用地址。

    綜上所述,都是我在北京尚學堂學習的時候做的筆記

  • 6 # 日衝資訊 黃

    先來看個例子:

    String str=“Hello”;String ptr=new String(“Hello”);

    在這個例子中第1行的字串物件中存放的是一個字串的值。在傳遞這個引數的時候,Java複製這個字串的值到函式內部物件中,我們在函式中修改字串的值,並不能改變外部物件的字串。也就是所謂的傳值了。

    第2行的字串物件中存放的是另一個字串物件的引用。在傳遞這個引數的時候,Java也複製這個引數的值到函式內部物件中,只是這一次複製的是引用,這樣我們在函式中修改字串的值就會直接改變被引用的字串。

    可見,Java也可以傳遞引用。概念上,Java不區分引用和值,而是把它們稱為物件和例項。

  • 7 # 鬥戰勝佛

    值傳遞(pass by value)是指在呼叫函式時將實際引數複製一份傳遞到函式中,這樣在函式中如果對引數進行修改,將不會影響到實際引數。

    引用傳遞(pass by reference)是指在呼叫函式時將實際引數的地址直接傳遞到函式中,那麼在函式中對引數所進行的修改,將影響到實際引數。

    區別:

    值傳遞和引用傳遞的區別並不是傳遞的內容。而是實參到底有沒有被複制一份給形參。

    總結:

      Java中其實還是值傳遞的,只不過對於物件引數,值的內容是物件的引用,所以就不是引用傳遞。

    無論是值傳遞還是引用傳遞,其實都是一種求值策略(Evaluation strategy)。在求值策略中,還有一種叫做按共享傳遞(call by sharing)。其實Java中的引數傳遞嚴格意義上說應該是按共享傳遞。

    按共享傳遞,是指在呼叫函式時,傳遞給函式的是實參的地址的複製(如果實參在棧中,則直接複製該值)。在函式內部對引數進行操作時,需要先複製的地址尋找到具體的值,再進行操作。如果該值在棧中,那麼因為是直接複製的值,所以函式內部對引數進行操作不會對外部變數產生影響。如果原來複製的是原值在堆中的地址,那麼需要先根據該地址找到堆中對應的位置,再進行操作。因為傳遞的是地址的複製所以函式內對值的操作對外部變數是可見的。

    簡單點說,Java中的傳遞,是值傳遞,而這個值,實際上是物件的引用。

    而按共享傳遞其實只是按值傳遞的一個特例罷了。所以我們可以說Java的傳遞是按共享傳遞,或者說Java中的傳遞是值傳遞。

  • 8 # 科技分享愛好者

    許多初學者都有這個疑問,java是值傳遞還是引用傳遞?

    先介紹疑問的出處,兩派的觀點。

    小A說:java是值傳遞

    小A說你看上面的程式碼,呼叫jia方法之前a是1,呼叫方法之後還是1,值沒有改變。

    小B說:java是引用傳遞

    小B說你看上面的程式碼,呼叫chang方法之前陣列為{1},呼叫方法之後是{2},改變了值。

    答案:java是值傳遞

    小B的觀點是有失偏頗的,單純的根據值的變化判斷是不是引用傳遞是錯誤。

    我們可以來看一下下面的程式碼:

    若java是引用傳遞,那麼陣列a和b在交換之後,內容應該互相交換,但是結果仍然不變。

    為什麼不會變呢?

    因為java方法的引數傳遞是引用複製傳遞。

    在呼叫swap方法,x變數複製了a的引用指向1,y變數複製了b的引用指向2(如圖)。

    2. 在呼叫int[] t = x;x = y;y = t;方法,x指向2,y指向1,ab指向沒變(如圖)。

    3. 當方法結束後,引數xy變數失效,引數變數a和b沒有改變,沒有受到影響。

    總結

    什麼時候會改變,什麼時候不會改變呢?

    一個方法不能修改一個基本資料型別的引數(即數值型或布林型)。

    一個方法可以改變一個物件引數的狀態。一個方法不能讓物件引數引用一個新的物件。

  • 中秋節和大豐收的關聯?
  • 有人說農業的出路是機械化,你覺得呢?