今天做項目,發現了一個問題,當String作為參數傳遞的時候,在函數内部改變值對外部的變量值無影響,如下代碼:
一開始很不解,後來想明白了,遂去對java參數傳遞做一個總結,以加深自己的基礎知識.
對于:
整型: byte short int long
浮點型 float double
邏輯型 boolean
字元型 char
四類八種基本類型來說,傳遞的都是值,因為這些值是直接儲存在棧記憶體中的,是以傳遞的時候直接拷貝過去了.
結構如下圖,也是以最外層的num的值并沒有受到影響.

對象傳遞,本質上也都是值傳遞,隻不過傳遞的值是該引用的拷貝.看下面執行個體和圖解:
結構圖如下:
當執行change的時候,會把person變量的指向的位址拷貝一份給personChange,兩者都指向同一個堆記憶體,即使後面做了set方法修改,但是對兩者的執行毫無影響.
例二和之前的不同之處在change裡面,對personChange進行了new操作.代碼如下:
當執行change的時候,會把person變量的指向的位址拷貝一份給personChange,兩者都指向同一個堆記憶體,接下new操作會在堆中重新建立一個person對象,此時personChange則指向這個對象,而原person的指向沒發生變化,故輸出aaa 11.
例三是綜合例一和例二,前面兩個搞懂的話這個就很容易懂了.
讀者自己了解下,不懂的話再看看前面的,看看為什麼輸出CCC 11
終于到最初的問題,為什麼String是對象,但是卻不符合上面對象傳遞測試出來的結果?
原因:
因為String對象具有不可變性,是以針對操作str = "22222",在String池中不存在的時候,就是相當于str = new String(),這樣變化下的話,那麼就和例一 一模一樣了,具體圖就不畫了,希望對你有幫助.
ps:如果想改變的話,可以使用Holder包裝類包裝String,可以參考博文:Java基礎系列18:Holder技術的實作原理分析 | zifangsky的個人部落格
要了解上面的結果,就要認為Java中隻有值傳遞:
對于基本類型,直接拷貝值傳遞過去
對于對象,拷貝目前對象的引用位址,然後把該位址傳遞過去,是以也是值傳遞.