1、示例图
2、代码
实现原型模式的核心类
/**
* 1、实现Cloneable接口
* 2、实现clone方法
*/
public class Sheep implements Cloneable{
private String name;
private int age;
public Sheep(String name, int age) {
this.name = name;
this.age = age;
}
//clone该实例使用默认的方法clone
@Override
protected Object clone() {
Sheep sheep = null;
try{
sheep = (Sheep) super.clone();
}catch(Exception e){
System.out.println(e.toString());
}
return sheep;
}
}
继承了Sheep
public class SheepImpl extends Sheep {
public SheepImpl(String name, int age) {
super(name, age);
}
}
运行测试原型模式
public class ProtoTypeTest {
public static void main(String[] args) {
SheepImpl sheep = new SheepImpl("洋洋",1);
SheepImpl cpSheep = (SheepImpl) sheep.clone();
System.out.println(sheep == cpSheep); //为false 不是同一个对象
}
}
3、优点
1)在解决克隆羊的问题上比用传统方式效率高,减少了在类初始化对于资源的消耗
4、浅拷贝
如果在Sheep中包含一个其他的对象的属性,在clone之前对该对象的该属性赋值,即该属性是引用对象,当该属性被修改时会影响到其他clone的对象。(注:这里的clone方法都是默认的clone方式)
Sheep类新增Sheep属性
public class Sheep implements Cloneable{
private String name;
private int age;
private Sheep sheep;
}
运行代码
public class ProtoTypeTest {
public static void main(String[] args) {
SheepImpl sheep = new SheepImpl("洋洋",1);
SheepImpl friend = new SheepImpl("哈哈",2);
sheep.setSheep(friend);
//默认使用默认的clone
SheepImpl cpSheep = (SheepImpl) sheep.clone();
//新增的属性Sheep的hashCode相同,即浅拷贝
System.out.println(sheep.getName() + "--" + sheep.getAge() + "--" + sheep.getSheep().hashCode());
System.out.println(cpSheep.getName() + "--" + cpSheep.getAge() + "--" + cpSheep.getSheep().hashCode());
System.out.println(sheep == cpSheep); //false 不是同一个对象
}
}
运行结果
洋洋--1--460141958
洋洋--1--460141958
false
4、深拷贝的两种方法
主要的深拷贝方法都在这个类中
public class DeepClone implements Cloneable, Serializable {
private static final long serialVersionUID = -1464966484283440495L;
private String name;
private int age;
private DeepCloneTarget deepCloneTarget;
public DeepClone(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public DeepCloneTarget getDeepCloneTarget() {
return deepCloneTarget;
}
public void setDeepCloneTarget(DeepCloneTarget deepCloneTarget) {
this.deepCloneTarget = deepCloneTarget;
}
/**
* 深拷贝 方式1
*/
@Override
protected Object clone() throws CloneNotSupportedException {
DeepClone deep = null;
//1、对基本数据类型进行clone(使用默认的clone)
deep = (DeepClone)super.clone();
//2、将引用对象进行,单独处理
deep.setDeepCloneTarget((DeepCloneTarget)deepCloneTarget.clone());
return deep;
}
/**
* 深拷贝 方式2
* 通过序列化clone
*/
public Object deepClone(){
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try{
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
DeepClone cpDeepClone = (DeepClone) ois.readObject();
return cpDeepClone;
}catch (Exception e){
e.printStackTrace();
return null;
}finally {
//关闭流
try {
bos.close();
bis.close();
oos.close();
ois.close();
}catch (Exception e2){
e2.printStackTrace();
}
}
}
}
DeepClone的属性
public class DeepCloneTarget implements Cloneable, Serializable {
private static final long serialVersionUID = -4163686254455988446L;
private String Name;
private int no;
public DeepCloneTarget(String name, int no) {
Name = name;
this.no = no;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
//在这里全部属性都是基本数据类型,则使用默认的clone即可
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
运行代码
public class DeepCloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
DeepClone deepClone = new DeepClone("aaa",11);
deepClone.setDeepCloneTarget(new DeepCloneTarget("vvv",22));
//方式1 深拷贝
DeepClone cpDeepClone = (DeepClone) deepClone.clone();
System.out.println("深拷贝 方式1");
System.out.println(deepClone == cpDeepClone);
System.out.println("deepClone.DeepCloneTarget = "+deepClone.getDeepCloneTarget().hashCode());
System.out.println("cpdeepClone.DeepCloneTarget = "+cpDeepClone.getDeepCloneTarget().hashCode());
//方式2 深拷贝 序列化
DeepClone cpDeepCloneSerial = (DeepClone) deepClone.deepClone();
System.out.println("深拷贝 方式2");
System.out.println(deepClone == cpDeepCloneSerial);
System.out.println("deepClone.DeepCloneTarget = "+deepClone.getDeepCloneTarget().hashCode());
System.out.println("cpDeepCloneSerial.DeepCloneTarget = "+cpDeepCloneSerial.getDeepCloneTarget().hashCode());
}
}
运行结果
深拷贝 方式1
false
deepClone.DeepCloneTarget = 460141958
cpdeepClone.DeepCloneTarget = 1163157884
深拷贝 方式2
false
deepClone.DeepCloneTarget = 460141958
cpDeepCloneSerial.DeepCloneTarget = 2065951873