原型 就好比:一个孙悟空的变出多个一样的孙悟空一样
* java的构件模型直接支持原始模式的。
* 所有的javaBean都继承Object,而Object类提供一个clone方法
* 可以将一个JavaBean对象复制一份。
* 但这个JavaBean必须实现一个标识接口:Cloneable.
* -----------------------
* 克隆满足的条件:
* clone方法将对象复制一份并返还给调用者。所谓“复制”的含义与clone方法是怎么
* 实现的有关。一般而言,clone方法满足以下的描述
* 1.对任何的对象X,都有:X.clone()!=X 克隆对象与原对象不是同一个对象
* 2. X.clone().getClass() == X.getClass() 克隆对象与原对象的类型是一样的
* 3. 如果对象X的equals()方法定义恰当的话,那么X.clone().equals(X) 是成立的。
* (Object类中equals()方法的默认实现是return (this==obj) 也就是说,当两个变量指向同一个对象时才返回true)
模式实现-浅复制和深复制
如下例子:
/** * 孙大圣 */ public class Monkey implements Cloneable, Serializable { private static final long serialVersionUID = -5655707590382020734L; private int height; private int weight; private GoldRingedStaff staff; private Date birthDate; public Monkey() { this.birthDate = new Date(); this.staff = new GoldRingedStaff(); } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } public GoldRingedStaff getStaff() { return staff; } public void setStaff(GoldRingedStaff staff) { this.staff = staff; } public Date getBirthDate() { return birthDate; } public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } //深克隆 // 利用串行化做深复制 (把对象写到流里的过程是串行化(Serilization)过程) public Object deepClone() throws IOException, ClassNotFoundException { // 将对象写到流里 ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(this); // 从流里读回来 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); return ois.readObject(); } //这是浅克隆 @Override protected Object clone() throws CloneNotSupportedException { return (Monkey) super.clone(); } @Override public String toString() { return "birthDate=" + birthDate + " height=" + height + " weight=" + weight + " GoldRingedStaff=" + staff; } }
//金箍棒 public class GoldRingedStaff implements Cloneable, Serializable { private static final long serialVersionUID = -206209645135740010L; // 高度 private float height = 100.0F; // 直径 private float diameter = 100.0f; public GoldRingedStaff() { } // 增长和增大 public void grow() { this.diameter *= 2.0; this.height *= 2.0; } // 缩小和变短 public void shrink() { this.diameter /= 2.0; this.height /= 2.0; } //移动 public void move(){ } public float getHeight() { return height; } public void setHeight(float height) { this.height = height; } public float getDiameter() { return diameter; } public void setDiameter(float diameter) { this.diameter = diameter; } @Override public String toString() { return "height=" + height + " diameter" + diameter; } }
//测试 public class MainApp { private Monkey money = new Monkey(); void change() throws Exception { Monkey copyMoney; Thread.sleep(1000); copyMoney = (Monkey) money.clone(); System.out.println(" Money="+money); System.out.println("copyMoney="+copyMoney); System.out.println("money==copyMoney?"+(money==copyMoney)); System.out.println((money.getStaff() == copyMoney.getStaff())?"money.getStaff() == copyMoney.getStaff()":"money.getStaff() != copyMoney.getStaff()"); Thread.sleep(1000); System.out.println("---------------deep Copy------------------------------------"); copyMoney = (Monkey) money.deepClone(); System.out.println(" Money="+money); System.out.println("copyMoney="+copyMoney); System.out.println("money==copyMoney?"+(money==copyMoney)); System.out.println((money.getStaff() == copyMoney.getStaff())?"money.getStaff() == copyMoney.getStaff()":"money.getStaff() != copyMoney.getStaff()"); } /** * * 浅复制 * 只对当前象进行复制,而不对其引用对象进行提制 * 这说明复制出来的东西不是同一个对象,但是这两个对象所引用的对象却是同一个 * * 深复制 * 所要复制的对象都要实现 Serializable接口和Cloneable接口 * 这说明复制出来的东西不是同一个对象,而且这两个对象所引用的对象也不是同一个对象 */ public static void main(String[] args) { try { new MainApp().change(); } catch (Exception e) { e.printStackTrace(); } //out put 输出如下 /*Money=birthDate=Tue Dec 07 00:28:21 CST 2010 height=0 weight=0 GoldRingedStaff=height=100.0 diameter100.0 copyMoney=birthDate=Tue Dec 07 00:28:21 CST 2010 height=0 weight=0 GoldRingedStaff=height=100.0 diameter100.0 money==copyMoney?false money.getStaff() == copyMoney.getStaff() ---------------deep Copy------------------------------------ Money=birthDate=Tue Dec 07 00:28:21 CST 2010 height=0 weight=0 GoldRingedStaff=height=100.0 diameter100.0 copyMoney=birthDate=Tue Dec 07 00:28:21 CST 2010 height=0 weight=0 GoldRingedStaff=height=100.0 diameter100.0 money==copyMoney?false money.getStaff() != copyMoney.getStaff()*/ } }