浅克隆Demo:
羊:
package prototype_mode; import java.util.Date; /** * 羊 * 对象要可以克隆, 需要实现空接口, 标记接口Cloneable, 这是规范 * clone是object方法, c实现, 效率极高 */ public class Sheep implements Cloneable { private String sname; private Date birthday; /** * 覆盖父类(Object)的克隆方法, 测试浅克隆 */ @Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone();//直接调用object对象的clone()方法进行克隆, 返回克隆后的对象! return obj; } public Sheep(){ } public Sheep(String sname, Date birthday) { this.sname = sname; this.birthday = birthday; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }
概念图:
测试类:
package prototype_mode; import java.util.Date; /** * 测试原型模式, 浅克隆 */ public class Client { public static void main(String[] args) throws CloneNotSupportedException { //创建原型对象 Sheep s1 = new Sheep("少利", new Date(12312312312l)); System.out.println(s1 + ": " + s1.getSname() + ", " + s1.getBirthday()); //克隆原型对象 Sheep s2 = (Sheep) s1.clone(); System.out.println(s2 + ": " + s2.getSname() + ", " + s2.getBirthday()); //修改克隆对象 s2.setSname("多利"); //1997年, 英国的克隆羊, 多利! s2.getBirthday().setTime(32132132132l); //打印两个对象 System.out.println("--------------------------------"); System.out.println(s1 + ": " + s1.getSname() + ", " + s1.getBirthday()); System.out.println(s2 + ": " + s2.getSname() + ", " + s2.getBirthday()); //结果: 克隆对date对象只是引用(值)克隆 } }
打印结果:
prototype_mode.Sheep@1db9742: 少利, Sat May 23 20:05:12 CST 1970 prototype_mode.Sheep@647e05: 少利, Sat May 23 20:05:12 CST 1970 -------------------------------- prototype_mode.Sheep@1db9742: 少利, Fri Jan 08 05:35:32 CST 1971 prototype_mode.Sheep@647e05: 多利, Fri Jan 08 05:35:32 CST 1971
深克隆Demo:
羊2号:
package prototype_mode; import java.util.Date; /** * 羊2号 */ public class Sheep2 implements Cloneable { //1997年, 英国的克隆羊, 多利! private String sname; private Date birthday; /** * 覆盖父类(Object)的克隆方法, 测试深克隆 */ @Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone();//直接调用object对象的clone()方法进行克隆, 返回克隆后的对象! //需要对Date对象也进行克隆, 如果Date对象中拥有对象, 也要一层一层的全部克隆 Sheep2 s = (Sheep2) obj; s.birthday = (Date) this.birthday.clone();//返回克隆后的Date! return obj; } public Sheep2(){ } public Sheep2(String sname, Date birthday) { this.sname = sname; this.birthday = birthday; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }
概念图:
测试类:
package prototype_mode; import java.util.Date; /** * 测试原型模式, 深克隆 */ public class Client2 { public static void main(String[] args) throws CloneNotSupportedException { //创建原型对象 Sheep2 s1 = new Sheep2("少利", new Date(12312312312l)); System.out.println(s1 + ": " + s1.getSname() + ", " + s1.getBirthday()); //克隆原型对象 Sheep2 s2 = (Sheep2) s1.clone(); System.out.println(s2 + ": " + s2.getSname() + ", " + s2.getBirthday()); //修改克隆对象 s2.setSname("多利"); //1997年, 英国的克隆羊, 多利! s2.getBirthday().setTime(32132132132l); //打印两个对象 System.out.println("--------------------------------"); System.out.println(s1 + ": " + s1.getSname() + ", " + s1.getBirthday()); System.out.println(s2 + ": " + s2.getSname() + ", " + s2.getBirthday()); //结果: 克隆对象时对Date也进行了克隆 } }
打印结果:
prototype_mode.Sheep2@1db9742: 少利, Sat May 23 20:05:12 CST 1970 prototype_mode.Sheep2@647e05: 少利, Sat May 23 20:05:12 CST 1970 -------------------------------- prototype_mode.Sheep2@1db9742: 少利, Sat May 23 20:05:12 CST 1970 prototype_mode.Sheep2@647e05: 多利, Fri Jan 08 05:35:32 CST 1971
以序列化形式深克隆Demo:
羊3号:
package prototype_mode; import java.io.Serializable; import java.util.Date; /** * 羊3号 * 序列化UID唯一标识. * 反序列化时,如果UID不一致,就无法实现反序列化,并且将抛出InvalidClassException.[方法,域不能减,可以增,向后兼容] * 如果不显式指定,VM默认生成一个(耗费资源),但反序列化时会出问题. */ public class Sheep3 implements Cloneable, Serializable { private static final long serialVersionUID = 1218060507823188744L; private String sname; private Date birthday; public Sheep3(){ } public Sheep3(String sname, Date birthday) { this.sname = sname; this.birthday = birthday; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }
测试类:
package prototype_mode; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Date; /** * 测试原型模式, 深克隆 * 使用序列化和反序列化的方式实现深复制, 待复制对象需要实现Serializable接口 */ public class Client3 { public static void main(String[] args) throws Exception { //创建原型对象 Sheep3 s3 = new Sheep3("少利", new Date(12312312312l)); System.out.println(s3 + ": " + s3.getSname() + ", " + s3.getBirthday()); //使用序列化和反序列化实现深复制 //字节流形式 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos);//创建object输出流(传入字节数组输出流) oos.writeObject(s3);//序列化羊, 包括所有持有对象也一并 byte[] bytes = bos.toByteArray();//从字节数组输出流中, 获得字节数组 oos.close(); ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis);//创建object输入流(传入字节数组输入流) Sheep3 ss3 = (Sheep3) ois.readObject();//反序列化羊 ois.close(); System.out.println(ss3 + ": " + ss3.getSname() + ", " + ss3.getBirthday()); //文件流形式 // ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream(new File("D:\\file1"))); // oos2.writeObject(s3); // oos2.close(); // // ObjectInputStream ois2 = new ObjectInputStream(new FileInputStream(new File("D:\\file1"))); // Sheep3 ss3 = (Sheep3) ois2.readObject(); // ois2.close(); // System.out.println(ss3 + ": " + ss3.getSname() + ", " + ss3.getBirthday()); //修改复制对象 ss3.setSname("多利"); //1997年, 英国的克隆羊, 多利! ss3.getBirthday().setTime(32132132132l); //打印两个对象 System.out.println("--------------------------------"); System.out.println(s3 + ": " + s3.getSname() + ", " + s3.getBirthday()); System.out.println(ss3 + ": " + ss3.getSname() + ", " + ss3.getBirthday()); //结果: 序列化时, 对Date也进行了复制 } }
打印结果:
prototype_mode.Sheep3@1db9742: 少利, Sat May 23 20:05:12 CST 1970 prototype_mode.Sheep3@1311334: 少利, Sat May 23 20:05:12 CST 1970 -------------------------------- prototype_mode.Sheep3@1db9742: 少利, Sat May 23 20:05:12 CST 1970 prototype_mode.Sheep3@1311334: 多利, Fri Jan 08 05:35:32 CST 1971
谢谢声明出处!
转自: http://www.cnblogs.com/gscq073240/articles/7122287.html