(五)原型模式 Prototype
原型模式目的是复制一个现有对象来生成新的对象,而不是通过实例化的方式。原型模式需要实现 Cloneable 接口,覆写clone方法,复制分为浅复制、深复制。
浅复制:将一个对象复制后,基本数据类型的变量都重新创建,引用类型,指向的还是原对象所指向的。
深复制:讲一个对象复制后,不论基本数据类型和引用类型,都是重新创建,是完全的彻底的复制。
public class ProtoType {
public static void main(String[] args) throws Exception {
Father f=new Father();
User u1=new User("123456",f);
User u2=(User)u1.clone();
User u3=(User) u1.shallowClone();
System.out.println(u1==u2);//false
System.out.println(u1.f==u2.f);//false
System.out.println(u1.password == u2.password);//false
System.out.println(u1.f==u3.f);//true
System.out.println(u1.password == u3.password);//true
}
}
class User implements Cloneable,Serializable{
String password;
Father f;
public User(String password,Father f){
this.password=password;
this.f=f;
}
//浅复制
public Object shallowClone() throws CloneNotSupportedException{
User user = (User)super.clone();
return user;
}
//深复制
public Object clone() throws CloneNotSupportedException {
//return super.clone();
ObjectOutputStream out=null;
ObjectInputStream in=null;
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
out = new ObjectOutputStream(bo);
out.writeObject(this);
out.flush();
byte[] bs = bo.toByteArray();
ByteArrayInputStream bi = new ByteArrayInputStream(bs);
in = new ObjectInputStream(bi);
Object o = in.readObject();
return o;
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
finally{
try {
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class Father implements Serializable{}原型模式与调用构造函数相比,复制创建的新对象会包含原始对象的某些状态,尤其当多个对象的类在属性上存在细微差别,方法完全相同时候。
浅复制与深复制还存在一个问题就是引用类型成本的问题。对于代码来说就是 Father 值的问题,上面的代码修改下。
class Father implements Serializable{
String name = "father";
}
public static void main(String[] args) throws Exception {
Father f = new Father();
User u1 = new User("123456",f);
User u2 = (User)u1.clone();
User u3 = (User) u1.shallowClone();
u1.f.name = "aaaa";
System.out.println(u1.f.name);//aaaa 原型
System.out.println(u2.f.name);//father 深复制
System.out.println(u3.f.name);//aaaa 浅复制
}这样应该能跟深刻的理解了。
原文:http://blog.csdn.net/fanyun7654/article/details/37567035