相关点:
-
apache中反射实现原型模式 BeanUtils
-
jdk clone克隆(浅拷贝)
-
在Spring中Bean对象配置中的scope=“prototype”,每次使用对象之前,都会
创建一个对象,并且会将依赖关系完整的赋值给新创建的对象
Spring 默认是单例模式
浅拷贝: 如果是复制的是 引用类型,那么复制的就是引用类型的地址,并没有重新新建一个单独的引用类型,后面如果复制的新对象修改了这个引用的值就会影响之前的原型对象。基本类型没有什么影响,就是简单的赋值
深拷贝: 完完全全的把对象给复制了一遍,而不会像浅拷贝那样复制引用地址
1.使用序列化完成深克隆
需要实现Serializable接口,浅拷贝需要实现clone接口,重写clone方法
举例:
java提供clone方法就是浅拷贝
package com.prototype;
import java.io.*;
public class ProtoType implements Cloneable,Serializable{
private String name;
private User user;
//可以重写clone方法 ,浅拷贝
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
//深度克隆
public Object deepClone01() throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Object object = ois.readObject();
return object;
}
//笨的深度克隆
public ProtoType deepClone02() throws Exception {
ProtoType protoTypeClone = new ProtoType();
protoTypeClone.name = this.name;
protoTypeClone.setUser(new User(this.getUser().getuName(),this.getUser().getAge()));
return protoTypeClone;
}
...get,set方法省略
}
User类
public class User implements Cloneable,Serializable {
private String uName;
private int age;
public User() {
}
public User(String uName, int age) {
this.uName = uName;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
...get,set方法省略
}
测试:
package com.prototype;
public class TestProtoType {
public static void main(String[] args) throws Exception {
ProtoType protoType = new ProtoType();
protoType.setName("ws");
protoType.setUser(new User("vison",18));
ProtoType protoTypeClone = (ProtoType) protoType.clone();
ProtoType protoTypeDeepClone01 = (ProtoType) protoType.deepClone01();
ProtoType protoTypeDeepClone02 = protoType.deepClone02();
System.out.println("浅客隆"+(protoType == protoTypeClone)); //结果是false ,new一个新对象
System.out.println("浅客隆"+(protoType.getUser() == protoTypeClone.getUser())); //结果是true
System.out.println("深客隆01"+(protoType == protoTypeDeepClone01));//结果是false
System.out.println("深客隆01"+(protoType.getUser() == protoTypeDeepClone01.getUser()));//结果是false
System.out.println("深客隆02"+(protoType == protoTypeDeepClone02));//结果是false
System.out.println("深客隆02"+(protoType.getUser() == protoTypeDeepClone02.getUser()));//结果是false
}
}
2.使用笨循环赋值
这个其实就是把所有组合的引用类型都重新赋值,一直赋值到基本类型为止
如上面的这个方法。
//笨的深度克隆
public ProtoType deepClone02() throws Exception {
ProtoType protoTypeClone = new ProtoType();
protoTypeClone.name = this.name;
protoTypeClone.setUser(new User(this.getUser().getuName(),this.getUser().getAge()));
return protoTypeClone;
}
当然还有很多种方式实现。。。