package test;class Obj implements Cloneable{private int aInt=0;public int getAInt(){return aInt;}public void setAInt(int intl){aInt=intl;}public void changeInt(){this.aInt=1;}public Object clone(){Object o=null;try{o=(Object)super.clone();}catch(CloneNotSupportedException e){e.printStackTrace();}return o;}}public class Test{public static void main(String[] args){Obj a=new Obj();Obj b=(Obj)a.clone();b.changeInt();System.out.println("a:"+a.getAInt());System.out.println("b:"+b.getAInt());}}
程式啟動並執行結果為: a:0
b:1
在實際編程中,經常會遇到從某個已有的對象A建立出另外一個與A具有相同狀態的對象B,並且對B的修改不會影響到A的情況,例如Prototype(原型)模式中,就需要clone一個對象執行個體。在Java語言中,僅僅通過簡單的賦值操作顯然無法達到這個目的,而Java提供了一個簡單有效clone()方法來滿足這個需求。
Java中所有的類預設都整合Object類,而Object類中提供了一個clone()方法。這個方法的作用是返回一個Object對象的複製。這個複製函數返回的是一個新的對象而不是一個應用。那麼怎樣使用這個方法呢。以下是使用clone()方法的步驟。
1、實現clone()的類,首先需要整合Cloneable介面。Cloneable介面實質上是一個標識介面,沒有任何介面方法。
2、在類中重寫Object類中的clone()方法
3、在clone方法中調用super.clone()方法。無論clone類的繼承結構是什麼,super.clone()都會直接或間接的調用java.lang.Object類的clone方法。
4、把淺複製的引用指向原型對象新的複製體。
淺複製和深複製
Java語言在重載clone()方法時也會出現同樣的問題,當類中只有一些基本的資料類型時,採用上述方法就可以了,但是當類中包含了一些對象時,就需要用到深複製了,實現方法是對對象調用clone方法完成複製後,接著對對象中的非解百納類型的屬性也調用clone()方法完成深複製。具體案例如下:
package test;import java.util.Date;class Obj implements Cloneable{private Date birth=new Date();public Date getBirth(){return birth;}public void setBirth(Date birth){this.birth=birth;}public void changeDate(){this.birth.setMonth(4);}public Object clone(){Obj o=null;try{o=(Obj)super.clone();}catch(CloneNotSupportedException e){e.printStackTrace();}//實現深複製o.birth=(Date)this.getBirth().clone();return o;}}public class Test{public static void main(String[] args){Obj a=new Obj();Obj b=(Obj)a.clone();b.changeDate();System.out.println("a:"+a.getBirth());System.out.println("b:"+b.getBirth());}}
運行結果為: a:Sat Mar 28 19:46:34 CST 2015
b:Thu May 28 19:46:34 CST 2015
確保類中包含的所有非基本類型的成員變數都實現了深複製 Object o=super.clone(); //先執行淺複製 對每一個對象attr執行下列語句 o.attr=this.getAttr().clone();
淺複製和深複製區別:
淺複製:被複製對象的所有變數都含有與原來對象相同的值,而所有對象的其他對象的引用仍然指向原來的對象。換言之,淺複製所考慮的對象,而不複製它所引用的對象。
深複製:被複製對象的所有變數都含有與原來對象相同的值,除去那些引用其他對象的變數。哪些引用其他對象的變數將指向被複製的新對象,而不再是原有的那些被引用的對象。深複製的對象所引用的對象都複製了一遍。