在Java與C++中對象作為參數傳遞的不同


  問題源於在Java中使用對象作為參數,按照C++的思路進行調試,發現結果與C++中並不相同。

  導致該問題的原因是Java與C++對於對象的解釋是不相同的。

  在C++中對象作為參數采用的是“傳值調用”,當實參通過形參傳遞時,會調用對象(實參)的拷貝構造函數(如果沒有顯式的定義拷貝構造函數,將自動調用默認拷貝構造函數,它的功能是將實參中的對象原樣的拷貝到形參中,這里牽扯到深拷貝和淺拷貝的問題,但不影響對本問題的分析。),函數實際操作的是該對象的拷貝,並不影響原對象。

  而在Java中,對象作為參數時,形參是被初始化為實參對象的引用。如果對形參進行操作會影響到實參(原對象)。這有點類似於C++中的”引用調用“,但並非如此,Java中采用的仍然是”傳值調用“。而導致結果不同的原因是,Java與C++中對對象名的解釋是不同的。在C++中“類”和“對象”的關系可以類比為“類型”和“變量”之間的關系,對象在定義的時候即分配了內存空間,它是實實在在存在的。而在Java中,對象定義時只是定義了“對象變量”,它只是指向一個對象,當使用new操作符時才會構造指向的這個對象。Java中的對象名有點像C++中指向對象的指針,當作為參數傳遞時,傳遞的是該對象在內存中的地址。

  在C++和Java中String類的對象str的存儲方式分別如下:

 

  以Java中對象作為參數傳遞的例子分析一下:

 1 public class Test1 {
 2        public static void main(String[] args) {
 3         StringBuffer str = new StringBuffer("Hello ");
 4         System.out.println("Before change, str = " + str);
 5         changeData(str);
 6         System.out.println("After changeData, str = " + str);
 7     }
 8                                                                                     
 9        public static void changeData(StringBuffer strBuf) {
10         strBuf.append("World!");
11     }
12 }

   按照上面的分析,將str傳遞給strBuf 時,是將Hello存儲的地址傳遞過去,那么輸出結果是:

Before change, str = Hello
After changeData, str = Hello World!

  將上面的代碼修改一下,如下:

 1 public class Test2 {
 2        public static void main(String[] args) {
 3         StringBuffer str = new StringBuffer("Hello ");
 4         System.out.println("Before change, str = " + str);
 5         changeData(str);
 6         System.out.println("After changeData, str = " + str);
 7     }
 8                                                                                                                                                                                             
9
public static void changeData(StringBuffer strBuf) { 10 strBuf = new StringBuffer("Hi "); 11 strBuf.append("World!"); 12 } 13 }

  按照上面的分析,將str傳遞給strBuf 時,strBuf 與str都將存放Hello的存儲地址,如下圖:

  然后當執行完 strBuf = new StringBuffer("Hi "); 后,以上關系將變成:

  此時strBuf 中存放的不再是Hello的地址,而是Hi的地址,new操作符操作成功后總會在內存中新開辟一個存儲區域。

  當執行 strBuf.append("World!"); 這句時,此時操作的將是Hi,而不是Hello,那么結果將變成:

  最后輸出結果如下:

Before change, str = Hello
After changeData(n), str = Hello

 

  

 


免責聲明!

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



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