integer是值传递还是引用传递_值传递与引用传递
特點:傳遞的是值的拷貝,也就是傳遞后就互不相關了。
引用傳遞:指的是在方法調用時,傳遞的參數是按引用進行傳遞,其實傳遞的是引用的地址,也就是變量所對應的內存空間的地址。
特點:傳遞的是值的引用,也就是說傳遞前和傳遞后都指向同一個引用(也就是同一個內存空間)。
對于這兩種傳參方式,假如你寫過一些java程序后,你就會發現這不就是看傳的參數是基本類型的還是引用類型的嗎?(其中比較特殊一點的是String類型和基本類型的包裝類類型,它們也是按值傳遞的,但它是屬于引用類型,對于還不知道包裝類型的,可以看我之前的一篇博客:現世安穩:java學習基礎(三)關于自動拆箱與自動裝箱)
一、值傳遞
話不多說,我們直接分析代碼運行結果:
public 測試基本類型值傳遞對于基本類型,這里我只舉了int類型的值傳遞例子,可以看到在main方法里的a與test1方法里面的a并沒有什么關系,在test1方法里面改變a的值并不能影響main方法里的a值。
值傳遞,二者并不影響那對于引用類型String和基本類型的包裝類而言,它們也都是值傳遞。所以我們先來了解一波String類型。
public String類型采用值傳遞分析上面代碼,可以看出與int類型值傳遞的效果是一樣的。
對于String類型,我們有兩種常用的創建對象的方法,一種是用字符串直接量,一種是用字符數組。但java把字符串直接量也當做是String對象,因此,利用字符串直接量可以按如下兩種方式去創建。
//利用字符串直接值創建對象的方法但這兩種方式卻不能說完全一樣,且看測試代碼如下:
根據==判斷為false可知二者并不是指向同一個引用,但我們之前說String類型對象是不可變得,它的內容是不能改變的,既然根據equals判斷為true,它們的內容是一樣的,那為什么二者卻不是指向同一個引用呢?
其實,很簡單,正是由于字符串在程序設計中被頻繁使用,當它本身又不可變,所以JVM為了提高效率并節約內存,對具有相同字節序列的字符串直接量使用同一個實例。這個實例叫做“限定(interned)的字符串”。因此兩種創建對象的方式其實是不同的,s2是指向了一個限定的字符串“hello”,這個是在棧內存中的,而s1則是實實在在指向了創建的一個字符串對象,它的值為“hello”,這個則是在堆內存的。
兩種創建方式的比較假如你對什么是限定字符串和字符串不可變性的概念理解了,下面的一段代碼你就應該能很快理解了:
public分析:首先對于s1和s4大家應該好理解,創建了兩個對象,引用肯定是不相同的;其次對于限定字符串“hello”,由于s2與s3均指向它,因此二者的引用是相同的,所以s2==s3為true。至于s1和s2,上面已經解釋過了。最后我再說明一下String類型的不變性。看到s3輸出為helloworld,不明所以的你可能以為這個不就和不變性矛盾了嗎?其實不然,且看下圖:
不變性圖解(注:此圖有問題,"hello"以及“helloworld”都應該在棧內存中)看完圖,你就會明白,不變的是“hello”,但s3的引用關系發生了改變,指向了存放"helloworld"的內存空間。
二、引用傳遞
看完上面int和String類型的值傳遞,我們再來看下什么是引用傳遞。事實上,java里面參數傳遞只有值傳遞一種,因為引用傳遞可以相當于傳遞的是引用值。至于引用值是什么,我們可以類比C語言得指針變量,它存放的也是一段內存空間的地址。
引用傳遞事實上更好理解,尤其是你對C語言中指針概念有所了解的話,這個直接分析一遍代碼,就能理解了。
public 引用傳遞測試結果首先在main方法中,我們創建了A類的一個對象a,并把它的age設為2,然后我們將a作為參數傳到test1方法中,并再次修改age值,然后輸出test1中a.age值,執行完后返回到main函數里,再輸出main中a.age,且二者結果一致。結合內存圖示來理解,會很容易理解:
引用傳遞在不同方法之間,看似傳遞的是一個對象,但其實對象的位置并沒有動,只是將存放對象的內存地址進行了傳遞,這樣當改變對象的一些屬性時,也會的的確確改變堆內存中對象的某些屬性值,因此返回到main函數后由于a依舊指向同一塊區域,所以去讀取數據的時候,值就會變化了。
總結
以上是生活随笔為你收集整理的integer是值传递还是引用传递_值传递与引用传递的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 动态改变控件的方法
- 下一篇: 【转】Linux/ubuntu下apac