Java中參數傳遞問題


前段時間對Java中參數傳遞問題有點困惑,不了解其中的含義。查閱了很多資料,這里談談自己對該問題的理解。

參數傳遞一般有兩種,一種是“傳值”,另一種是“傳地址值”。傳值是指在調用方法時,把參數的值傳遞給方法,而傳地址值則是給方法提供參數的地址值。Java中的參數傳遞方法都為傳值調用。下面我通過例子來驗證。

1.基本類型的參數傳遞      

 1 public class ParamTransfer {  2     public int money;  3     
 4     public void amethod(int i) {  5         System.out.println("方法得到的i的值:" + i);  6         i = i * 5;  7         System.out.println("方法執行語句i=i*5后i的值:" + i);  8         System.out.println("money的值:" + this.money);  9  } 10 
11     public static void main(String[] args) { 12         ParamTransfer pt = new ParamTransfer(); 13         pt.money = 100; 14  pt.amethod(pt.money); 15  } 16 
17 }
運行結果如下:
方法得到的i的值:100 方法執行語句i=i*5后i的值:500 money的值:100

注意對比形參i和money值的變化。這里我們把pt.money作為參數傳遞給amethod方法,該方法中i得到的值是100,這個我們從運行結果中可知。執行完i=i*5語句后我們發現當前對象的money屬性值並沒有發生改變,這就說明這里只是傳了一個100數值給形參i,相當於把pt.money的值拷貝給i,i的變化並不會影響pt.money的值,僅僅是傳數值。

2.引用類型的參數傳遞

 1 class Time {  2     public int hour;  3     public int minute;  4     public int second;  5 }  6 
 7 public class ObjectParamTransfer {  8  Time time;  9 
10     public static void main(String[] args) { 11         ObjectParamTransfer opt = new ObjectParamTransfer(); 12         opt.time = new Time(); 13         opt.time.hour = 11; 14         opt.time.minute = 22; 15         opt.time.second = 33; 16 
17         System.out.println("time的屬性值:"); 18         System.out.println("hour=" + opt.time.hour); 19         System.out.println("minute=" + opt.time.minute); 20         System.out.println("second=" + opt.time.second); 21 
22         opt.method(opt.time);//將對象引用作為參數傳遞給方法method 23         //對比執行方法后的變化
24         System.out.println("執行方法后的time的屬性值"); 25         System.out.println("hour=" + opt.time.hour); 26         System.out.println("minute=" + opt.time.minute); 27         System.out.println("second=" + opt.time.second); 28 
29  } 30 
31     private void method(Time t) { 32         System.out.println("參數t的屬性值:"); 33         System.out.println("hour=" + t.hour); 34         System.out.println("minute=" + t.minute); 35         System.out.println("second=" + t.second); 36         System.out.println("對t和time進行==比較,結果為:" + (t == this.time)); 37 
38         System.out.println("改變t的實例變量值"); 39         t.hour = 44; 40         t.minute = 55; 41         t.second = 60; 42  } 43 }
運行結果如下:
time的屬性值: hour
=11 minute=22 second=33 參數t的屬性值: hour=11 minute=22 second=33 對t和time進行==比較,結果為:true 改變t的實例變量值 執行方法后的time的屬性值: hour=44 minute=55 second=60

將對象引用opt.time傳遞給method方法后先輸出參數t的屬性值,發現和原來對象引用的屬性值是相同的。進一步返回t==this.time的結果為true。改變t的實例變量值后,當前引用opt.time的屬性值也隨之發生改變。這就充分證明了參數t和對象引用opt.time指向同一對象,即它們指向的內存空間地址一致。那么問題來了,到底是opt.time這個引用傳遞了內存空間地址值給參數t還是它自己就是這個參數t呢?這我們不得而知。下面再通過一個例子來證明。

 1 public class ObjectParamTransfer2 {  2  Time time1;  3  Time time2;  4 
 5     public static void main(String[] args) {  6         ObjectParamTransfer2 opt = new ObjectParamTransfer2();  7         opt.time1 = new Time();  8         opt.time2 = new Time();  9         opt.time1.hour = 12; 10         opt.time2.hour = 23; 11         System.out.println("交換前的值:"); 12         System.out.println("time1.hour=" + opt.time1.hour); 13         System.out.println("time2.hour=" + opt.time2.hour); 14 
15  opt.swap(opt.time1, opt.time2); 16         System.out.println("交換后的值:"); 17         System.out.println("time1.hour=" + opt.time1.hour); 18         System.out.println("time2.hour=" + opt.time2.hour); 19  } 20 
21     private void swap(Time t1, Time t2) { 22  Time temp; 23         temp = t1; 24         t1 = t2; 25         t2 = temp; 26  } 27 
28 }
運行結果如下:
交換前的值: time1.hour
=12 time2.hour=23 交換后的值: time1.hour=12 time2.hour=23

這里寫了一個交換兩個引用的swap的方法。但是我們從結果中發現調用該方法后輸出結果並沒有發生改變。說明該方法並沒有對opt.time1和opt.time2這兩個引用進行交換。在該方法中只是對參數t1,t2進行交換,驗證了上個例子中引用傳遞的是內存空間地址值,並非參數就是該引用(即傳的不是引用)。對參數的操作並不會影響原來的引用,只會影響參數和引用所指的同一個內存空間里面的內容。這就證明了引用類型參數傳遞並不是傳引用,而只是傳該引用的內存地址值。

3.參數傳遞中的一種特殊情況

在上面的例子中我們已經知道了基本類型的參數傳遞傳的是傳數值,引用類型的參數傳遞傳的是內存地址值。但我在學習過程中碰到一種特殊情況:

 1 public class Test {  2     public static void main(String[] args) {  3         String str = new String("abc");  4  change1(str);  5  System.out.println(str);  6  }  7     
 8     private static void change1(String str1) {  9         str1 += "123"; 10  System.out.println(str1); 11  } 12 }
運行結果:
abc123 abc

按上面得出的結論來看,引用類型的參數傳遞傳遞的是內存地址值,str和str1指向的是同一個內存空間,str1將內存空間里面的內容改變后輸出str也應該發生改變。但是str指向的內存空間里的內容“abc”並沒有發生變化。這里我理解為String類型的引用傳遞傳的是內容,並不是內存空間地址值。(與第一個例子中傳數值類似)並不會影響原來引用所指的內存空間的內容。可能這也是String對象內容不可變的原因?

因為目前還在基礎階段,學習的還不夠深刻自己也有點疑問,以上理解可能存在偏差和錯誤,如有錯誤請大家指出。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM