為什麼說java裡面只有值傳遞?

葉宗琪


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

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

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

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

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

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

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

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

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

我是『Java實戰技術』,關注我獲取更多原理分析、實戰技術!


Java實戰技術


“Java語言只有值傳遞”,要理解這個知識點,確實有點難度。


1、首先,我們瞭解一下Java語言的數據類型。

Java語言有兩大類數據類型:


(1)基本類型:有八種:byte、short、int、long、float、double、char、boolean;

(2)引用類型。


2、方法調用時,如果參數為基本類型,是值傳遞。

這個比較容易理解,我們舉個例子:


我們對程序進行編譯和運行,情況如下:


顯然,如果方法的參數是基本類型,實參的值不會被方法改變,參數是值傳遞的方式。


3、方法調用時,如果參數為引用類型,也是值傳遞。

我們先看下面的例子:


對程序進行編譯和運行,情況如下:


從上面的例子可以看出,如果方法的參數是引用類型,實參的值不會被方法改變,參數也是值傳遞的方式。


也許您一看第二個例子,立即明白了道理。

也許您的反應是:我要的不是這個例子!!!

您要的是下面的例子——


4、方法調用時,如果參數為引用類型,雖然是值傳遞,實參的值不會改變,但實參指向的對象的屬性可能會被改變。

這個例子也許是您心中想的:


對程序進行編譯和運行,情況如下:


這個例子,其實包含兩層意思:

(1)main()方法中的valueTest3變量的值,在調用changeValue()前後都沒有改變;

(2)但是main()方法中的valueTest3變量是引用,它指向的對象的theValue屬性改變了。


如果您對Java語言感興趣,可以關注我,我們可以一起討論有趣的技術問題。


謝謝您的瀏覽!


編程實踐


先來看個例子:

  1. String str=“Hello”;
  2. String ptr=new String(“Hello”);

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

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

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


分享到:


相關文章: