1. 程式人生 > >java 中的值傳遞,與引用傳遞

java 中的值傳遞,與引用傳遞

個人理解:

基本型別在方法中傳遞引數,僅僅是拷貝的值做出改變,自身沒有任何變化,所以,基本型別在作為引數傳入後,自身沒有任何的改變。

引用型別傳入方法的是自身的地址的拷貝,如果通過對拷貝的地址所指向的物件進行操作那麼物件會發生變化,因為兩個地址指向的是同一個物件,如果拷貝的地址指向的一個新的物件,那麼原物件是不會改變的。

值傳遞和引用傳遞的本質區別在於是否在傳遞的時候進行物件的記憶體拷貝

基本型別是由於在JVM中儲存區域不同於普通物件所以傳遞前會拷貝,傳遞的是拷貝後的值,但是物件在傳遞的時候不拷貝,直接傳“引用值”,指向同一片物件堆記憶體區域,當然要注意String這種特殊情況。

  1. publicclass Example {    
  2.     String str = new String("abc");    
  3.     char[] ch = { 'a''b''c' };    
  4.     publicstaticvoid main(String args[]) {    
  5.         Example ex = new Example();    
  6.         ex.change(ex.str, ex.ch);    
  7.         System.out.println(ex.str);    
  8.         System.out.println(ex.ch);    
  9.     }    
  10.     publicvoid change(String str, char ch[]) {  
  11.         //ch = new char[]{'a','b','c'};  
  12.         str = "change";    
  13.         ch[0] = 'c';    
  14.     }    
  15. }    

這個例子的輸出為:

  1. abc  
  2. cbc  

要知道String和char陣列都是引用型別,不是基本型別。

當我們把str作為引數傳入方法後,會新建另一個變數,已經不是原來的變量了,但是他們指向的資料區域都一樣,所以如果你在方法中改變了str指向的資料區域,即執行str = "change",那也只是改變新建的另一個變數所指向的資料區域

,即指向一個新物件"change",str仍然指向原來的資料區域。所以會輸出abc

但是對於char陣列的例子呢,即物件型別,也就是Object的子類(除了String,是把ch的引用傳遞進來,即引用傳遞。這樣裡面和外面的ch都指向了相同的資料區域,執行ch[0] = 'c',就會把這個資料區域裡的第一個字元改成c,並沒有改變內部ch的資料地址,所以這個修改也會反映到外部的ch。所以會輸出cbc。如果你改變了內部ch所指向的資料區域,即把上面程式碼中註釋的那一行開啟,即執行ch = new char[]{'a','b','c'},這樣ch已經指向一個新的資料區域。輸出的結果肯定也就是abc了。

(1)基本資料型別傳值,對形參的修改不會影響實參;
(2)引用型別傳引用,形參和實參指向同一個記憶體地址(同一個物件),所以對引數的修改會影響到實際的物件;
(3)String, Integer, Double等immutable的型別特殊處理,可以理解為傳值,最後的操作不會修改實參物件。