在Object中有clone()方法 PRotected Object clone() throws CloneNotSupportedException
clone()的作用是創建一個該對象的一個副本,并將對象的數據復制到該副本中
根據復制程度的不同,clone可以分為: 淺拷貝:使用clone()即為淺拷貝,默認的拷貝方式是復制一個新的原對象,并賦予原對象相同的全局對象的值和引用。即原對象和復制對象的全局引用變量指向的是一個相同的對象空間。 深拷貝:需要自己實現,即將原對象中的全局引用變量指向的對象也復制一份放入復制對象中。
這兩個概念可能不太好理解,可以根據下面的案例來加深理解。
首先明確對Object clone的要求
實現Cloneable接口,如果不實現該接口會在clone方法中拋出CloneNotSupportedException異常需要重寫clone方法,clone方法在Object中是protect的,不能被外部訪問,需要重寫并修改為public的訪問權限。運行類
class Test{ @Test public void ttt() throws CloneNotSupportedException { A a=new A(); B b=new B(); a.setName("one"); a.setB(b); b.setAge(1); A ca= (A) a.clone(); a.setName("two"); a.getB().setAge(2); System.out.print("a.name="+a.getName()+"/n"+ "a.b.age="+a.getB().getAge()+"/n"+ "ca.name="+ca.getName()+"/n"+ "ca.b.age="+ca.getB().getAge()); //打印 /* a.name=two a.b.age=2 ca.name=one ca.b.age=2 */ }}class A implements Cloneable{ private String name; private B b; public String getName() { return name; } public void setName(String name) { this.name = name; } public B getB() { return b; } public void setB(B b) { this.b = b; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); }}class B implements Cloneable{ private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); }}上面的案例即為淺拷貝,可以看到ca為a的拷貝對象,但是兩個對象的b指向的是同一個B的對象。
進行深拷貝: 需要修改A中的clone方法
@Overridepublic Object clone() throws CloneNotSupportedException { A o=null; o=(A)super.clone(); if(o.b!=null){ o.b=(B)o.b.clone(); } return o;}在test中的打印結果為:
a.name=twoa.b.age=2ca.name=oneca.b.age=1另一種利用序列化來實現對象的深拷貝 需要序列化,首先要讓A和B都實現Serializable接口 在A中添加深拷貝方法
public Object deepClone() throws IOException, ClassNotFoundException { ByteArrayOutputStream bo=new ByteArrayOutputStream(); ObjectOutputStream oo=new ObjectOutputStream(bo); oo.writeObject(this); ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi=new ObjectInputStream(bi); return oi.readObject();}該方法先將可序列化對象a寫入流中,再將對象從流中讀出來重建對象
參考博客: java.lang.Object.clone()分析 Java Object對象之clone方法 Object的clone()方法、深拷貝、淺拷貝
新聞熱點
疑難解答