天天看點

圖解JAVA參數傳遞

今天做項目,發現了一個問題,當String作為參數傳遞的時候,在函數内部改變值對外部的變量值無影響,如下代碼:

一開始很不解,後來想明白了,遂去對java參數傳遞做一個總結,以加深自己的基礎知識.

對于:

整型: byte short int long

浮點型 float double

邏輯型 boolean

字元型 char

四類八種基本類型來說,傳遞的都是值,因為這些值是直接儲存在棧記憶體中的,是以傳遞的時候直接拷貝過去了.

結構如下圖,也是以最外層的num的值并沒有受到影響.

圖解JAVA參數傳遞

對象傳遞,本質上也都是值傳遞,隻不過傳遞的值是該引用的拷貝.看下面執行個體和圖解:

結構圖如下:

當執行change的時候,會把person變量的指向的位址拷貝一份給personChange,兩者都指向同一個堆記憶體,即使後面做了set方法修改,但是對兩者的執行毫無影響.

圖解JAVA參數傳遞

例二和之前的不同之處在change裡面,對personChange進行了new操作.代碼如下:

圖解JAVA參數傳遞

當執行change的時候,會把person變量的指向的位址拷貝一份給personChange,兩者都指向同一個堆記憶體,接下new操作會在堆中重新建立一個person對象,此時personChange則指向這個對象,而原person的指向沒發生變化,故輸出aaa 11.

例三是綜合例一和例二,前面兩個搞懂的話這個就很容易懂了.

圖解JAVA參數傳遞

讀者自己了解下,不懂的話再看看前面的,看看為什麼輸出CCC 11

終于到最初的問題,為什麼String是對象,但是卻不符合上面對象傳遞測試出來的結果?

原因:

因為String對象具有不可變性,是以針對操作str = "22222",在String池中不存在的時候,就是相當于str = new String(),這樣變化下的話,那麼就和例一 一模一樣了,具體圖就不畫了,希望對你有幫助.

ps:如果想改變的話,可以使用Holder包裝類包裝String,可以參考博文:Java基礎系列18:Holder技術的實作原理分析 | zifangsky的個人部落格

要了解上面的結果,就要認為Java中隻有值傳遞:

對于基本類型,直接拷貝值傳遞過去

對于對象,拷貝目前對象的引用位址,然後把該位址傳遞過去,是以也是值傳遞.