在设计模式中的prototype模式中,要特别留意的是其中的深复制和浅复制,现在小结一下
1 浅复制
   当进行浅复制时,如果类中包含了子对象,当这个类的包含的子引用对象发生改变时,这个变化会同时出现在它的浅复制克隆的对象中
去,比如
public class Lay1 implements Cloneable {
 public int x;
 public Lay2 lay2;
 public Object clone()
 {
  Object clone=null;
  try
  {
   
   clone=super.clone();
  }
  catch (CloneNotSupportedException e)
  {
   
  }
  return clone;
 }}
Lay1中包含子对象lay2了,lay2指向一个类Lay2
public class Lay2 implements Cloneable {
 public int y;
 public Object clone()
 {
  Object clone=null;
  try
  {
   clone=super.clone();
  }
  catch (CloneNotSupportedException e)
  {
   
  }
  return clone;
   }}客户程序
public class Client {
   public static  void main(String argv[])
   {
     Lay1 obj1=new Lay1();
     obj1.lay2=new Lay2();
     obj1.x=1;
     obj1.lay2.y=1;
     Lay1 obj2=(Lay1)obj1.clone();
     obj2.x=2;
     obj2.lay2.y=2;
     System.out.println("obj1.x is:"+obj1.x+"\tObj1.lay2.y is:"+obj1.lay2.y);
     System.out.println("obj2.x is:"+obj2.x+"\tObj2.lay2.y is:"+obj2.lay2.y);
   }
 }输出为
obj1.x i s:1  obj1.lay2.y=2
obj2.x  is 2  obj2.lay2.y=
可以看到 obj1当前层的对象别clone了一份,但clone对象的值的改变不反映到父对象,但修改其引用的子对象lay2的值,会反映到父方,因为大家都是指向同一个地方嘛。
为了深复制,可以这样做
public class Lay1 implements Cloneable {
   public int x;
   public Lay2 lay2;
   public Object clone() {
   
    Lay1 temp=null;
     try {
     
      temp=(Lay1)super.clone();
      temp.lay2=(Lay2)lay2.clone();
     }
     catch (CloneNotSupportedException e) {
       // should never happen
     }
     return temp;
   }
 }
public class Lay2 implements Cloneable {
   public int y;
   public Object clone() {
     Object clone = null;
     try {
       clone = super.clone ();
     }
     catch (CloneNotSupportedException e) {
       // should never happen
     }
     return clone;
   }
 }
public class Client {
   public static  void main(String argv[])
   {
     Lay1 obj1=new Lay1();
     obj1.lay2=new Lay2();
     obj1.x=1;
     obj1.lay2.y=1;
     Lay1 obj2=(Lay1)obj1.clone();
     obj2.x=2;
     obj2.lay2.y=2;
     System.out.println("obj1.x is:"+obj1.x+"\tObj1.lay2.y is:"+obj1.lay2.y);
     System.out.println("obj2.x is:"+obj2.x+"\tObj2.lay2.y is:"+obj2.lay2.y);
   }可以看到。输出是
obj1.x is:1 Obj1.lay2.y is:1
obj2.x is:2 Obj2.lay2.y is:2
另外,给出C#版本的代码,注意C#中浅复制用到的memberwiseclone()
using System;
class ShallowCopy : ICloneable
{
public int[] v =
{1,2,3};
public Object Clone()
{
return this.MemberwiseClone();
}
public void Display()
{
foreach(int i in v)
Console.Write( i + ", ");
Console.WriteLine();
}
}
class Client
{
public static void Main()
{
ShallowCopy sc1 = new ShallowCopy();
ShallowCopy sc2 = (ShallowCopy)sc1.Clone();
sc1.v[0] = 9;
sc1.Display();
sc2.Display();
}
}
ShallowCopy对象实现了一个浅拷贝,因此当对sc1进行克隆时,其字段v并没有克隆,这导致sc1与sc2的字段v都指向了同一个v,因此,当修改了sc1的v[0]后,sc2的v[0]也发生了变化。
深复制
using System;
class DeepCopy : ICloneable
{
public int[] v =
{1,2,3};
// 默认构造函数
public DeepCopy()
{
}
// 供Clone方法调用的私有构造函数
private DeepCopy(int[] v)
{
this.v = (int[])v.Clone();
}
public Object Clone()
{
// 构造一个新的DeepCopy对象,构造参数为
// 原有对象中使用的 v
return new DeepCopy(this.v);
}
public void Display()
{
foreach(int i in v)
Console.Write( i + ", ");
Console.WriteLine();
}
}
class Client
{
public static void Main()
{
DeepCopy dc1 = new DeepCopy();
DeepCopy dc2 = (DeepCopy)dc1.Clone();
dc1.v[0] = 9;
dc1.Display();
dc2.Display();
}
}
这次在克隆的时候,不但克隆对象本身,连里面的数组字段一并克隆。因此,最终打印出来的dc1与dc2不同。










