首頁  >  文章  >  Java  >  Java中的「淺複製」與「深複製」的差異與實作(附程式碼)

Java中的「淺複製」與「深複製」的差異與實作(附程式碼)

angryTom
angryTom轉載
2019-11-26 15:53:102044瀏覽

Java中的「淺複製」與「深複製」的差異與實作(附程式碼)

將一個物件的參考複製給另一個對象,一共有三種方式。第一種方式是直接賦值,第二種方式是淺複製,第三種方式是深複製。

1.直接賦值

在Java中,A a1 = a2,這實際上複製的是引用,也就是說a1 和a2指向的是同一個物件。因此,當a1變化時,a2裡面的成員變數也會跟著改變。

2.淺複製(複製引用但不複製引用的物件)

#淺複製,又稱為淺拷貝。建立一個新對象,然後將當前對象非靜態欄位複製到該新對象,如果欄位是值類型的,那麼對該欄位執行複製;如果該欄位時引用類型的話,則複製引用但不複製引用的對象。因此,原始物件及其副本引用同一個物件。

(推薦影片:java影片教學)  

class Resume implements Cloneable{ 
     public Object clone() { 
         try { 
             return (Resume)super.clone(); 
         } catch (Exception e) { 
             e.printStackTrace(); 
         return null; 
         } 
     } 
}

3.深度複製(複製物件和其引用物件)

又稱深拷貝,不僅複製物件本身,而且複製物件包含的引用指向的所有物件。

class Student implements Cloneable {
         String name;
         int age;
         Professor p;
     Student(String name, int age, Professor p) {
         this.name = name;
         this.age = age;
         this.p = p;
     }
     public Object clone() {
         Student o = null;
         try {
             o = (Student) super.clone();
         } catch (CloneNotSupportedException e) {
             System.out.println(e.toString());
         }
     o.p = (Professor) p.clone();
     return o;
     }
}

使用clone()方法複製一個物件的步驟:

1)被複製的類別要實作Cloneable介面。

2)被複製的類別要重寫clone()方法。

那麼在程式設計時,要如何選擇使用哪一種複製方式呢?首先,檢查類別有無非基本類型(即物件)的資料成員。若沒有,則返回super.clone()即可。若有,請確保類別中包含的所有非基本類型的成員變數都實現了深複製。

引申:淺複製與深複製的差異?

淺複製(Shallow Clone):被複製的物件的所有變數都含有與原來物件相同的值,而所有其他物件的參考仍然指向原來的物件。換而言之,淺複製僅複製所考慮的對象,而不複製它所引用的對象。

深複製(Deep Clone):被複製物件的所有變數都含有與原來物件相同的值,除去那些引用其他物件的變數。那些引用其他對象的變數將指向被複製的新對象,而不是原有的那些被引用的對象。換而言之,深複製把複製的物件所引用的物件都複製了一遍。

擴充:

原型模式主要用於物件的複製,實作了介面(實作Cloneable介面),重寫一個方法(重寫Object類別中的clone ()方法),即完成了原型模式。

原型模式中的拷貝分為「淺拷貝」和「深拷貝」:

淺拷貝:對值類型的成員變數進行值的複製,對引用型別得成員變數只複製引用,不複製引用的物件。

拷貝:對值類型的成員變數進行值的複製,並且對引用類型的成員變數也進行引用物件的複製。

(Object類別的clone方法只會拷貝物件中的基本資料類型的值,對於陣列、容器物件、引用物件等都不會拷貝,這就是淺拷貝。如果要實現深拷貝,必須將原型模式中的陣列、容器物件、引用物件等另行拷貝。)

原型模式的優點:

1.如果建立新的物件比較複雜時,可以利用原型模式簡化物件的創建過程。

2.是永遠是模式創建物件比直接new一個物件在效能上好得多,因為Object類別的clone方法是一個本地方法,它直接操作記憶體中的二進位流,特別是複製大物件時,效能的差異非常明顯。

原型模式的使用場景:

因為上述優點,所以在需要重複地建立相似物件時可以考慮使用原型模式。例如需要在一個循環體內創建對象,如果對象創建過程比較複雜或者循環次數很多的話,使用原型模式不但可以簡化創建過程,而且可以使系統的整體性能提高很多。

本文來自php中文網,java教學欄目,歡迎學習!  

以上是Java中的「淺複製」與「深複製」的差異與實作(附程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除