
JAVA中浅复制与深复制 |
1.浅复制与深复制概念 class Student implements Cloneable![]() ...{ String name; int age; Student(String name,int age)![]() ...{ this.name=name; this.age=age; } public Object clone()![]() ...{ Object o=null; try![]() ...{ o=(Student)super.clone();//Object中的clone()识别出你要复制的是哪一个对象。 } catch(CloneNotSupportedException e)![]() ...{ System.out.println(e.toString()); } return o; }![]() public static void main(String[] args)![]() ...{ Student s1=new Student("zhangsan",18); Student s2=(Student)s1.clone(); s2.name="lisi"; s2.age=20; System.out.println("name="+s1.name+","+"age="+s1.age);//修改学生2后,不影响学生1的值。 } } ![]() 说明: class Professor ![]() ...{ String name; int age; Professor(String name,int age)![]() ...{ this.name=name; this.age=age; } } class Student implements Cloneable![]() ...{ String name;//常量对象。 int age; Professor p;//学生1和学生2的引用值都是一样的。 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; } public static void main(String[] args)![]() ...{ Professor p=new Professor("wangwu",50); Student s1=new Student("zhangsan",18,p); Student s2=(Student)s1.clone(); s2.p.name="lisi"; s2.p.age=30; System.out.println("name="+s1.p.name+","+"age="+s1.p.age);//学生1的教授成为lisi,age为30。 } }那应该如何实现深层次的克隆,即修改s2的教授不会影响s1的教授?代码改进如下。 class Professor implements Cloneable![]() ...{ String name; int age; Professor(String name,int age)![]() ...{ this.name=name; this.age=age; } public Object clone()![]() ...{ Object o=null; try![]() ...{ o=super.clone(); } catch(CloneNotSupportedException e)![]() ...{ System.out.println(e.toString()); } return o; } } 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![]() Student o=null; try![]() ...{ o=(Student)super.clone(); } catch(CloneNotSupportedException e)![]() ...{ System.out.println(e.toString()); } o.p=(Professor)p.clone(); return o; } public static void main(String[] args)![]() ...{ Professor p=new Professor("wangwu",50); Student s1=new Student("zhangsan",18,p); Student s2=(Student)s1.clone(); s2.p.name="lisi"; s2.p.age=30; System.out.println("name="+s1.p.name+","+"age="+s1.p.age);//学生1的教授不改变。 }![]() }
public Object deepClone()![]() ...{ //将对象写到流里 ByteArrayOutoutStream 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()); } 这样做的前提是对象以及对象内部所有引用到的对象都是可串行化的,否则,就需要仔细考察那些不可串行化的对象可否设成transient,从而将之排除在复制过程之外。上例代码改进如下。 class Professor implements Serializable![]() ...{ String name; int age; Professor(String name,int age)![]() ...{ this.name=name; this.age=age; } } class Student implements Serializable![]() ...{ String name;//常量对象。 int age; Professor p;//学生1和学生2的引用值都是一样的。 Student(String name,int age,Professor p)![]() ...{ this.name=name; this.age=age; this.p=p; } public Object deepClone() throws IOException,OptionalDataException,ClassNotFoundException![]() ...{ //将对象写到流里 ByteArrayOutoutStream 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()); } public static void main(String[] args)![]() ...{ Professor p=new Professor("wangwu",50); Student s1=new Student("zhangsan",18,p); Student s2=(Student)s1.deepClone(); s2.p.name="lisi"; s2.p.age=30; System.out.println("name="+s1.p.name+","+"age="+s1.p.age); //学生1的教授不改变。 } }![]() 4.参考资料 |