原型模式(克隆)
-
Prototype
-
拷贝与复制
-
IO流当然也可以实现拷贝,但是效率不如在内存中实现拷贝。
问题是,Java直接操作内存是比较麻烦的,就得将这部分工作交给C/C++。关键字native。
-
Object类中的clone()方法,Cloneable接口。
-
-
实现方法:
- 实现Cloneable接口
- 重写clone方法。
浅克隆
- 存在一个属性指向相同的内存空间(如Date属性),当一个对象修改该属性值的时候,另一个对象中的该属性也发生了变化。虽然对象之间是完全不同的(从hashcode可以看出,他们是完全不同的两个对象),但是他们的某些属性可能指向了相同的空间(可能默写属性的引用相同)。
原型类
package com.tiko.prototype.demo1;
import java.util.Date;
public class VideoProto implements Cloneable {
private String name;
private Date date;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public VideoProto() {
}
public VideoProto(String name, Date date) {
this.name = name;
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "VideoProto{" +
"name='" + name + '\'' +
", date=" + date +
'}';
}
}
测试
package com.tiko.prototype.demo1;
import java.util.Date;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//原型对象
Date date = new Date();
VideoProto v1 = new VideoProto("视频原型", date);
System.out.println("v1:"+v1);
System.out.println("v1:hash"+v1.hashCode());
//通过克隆创建新对象
VideoProto v2 = (VideoProto)v1.clone();//克隆出来的对象和原来是一样的
System.out.println("v2:"+v2);
System.out.println("v2:hash"+v2.hashCode());
System.out.println("通过clone对象修改属性...");//通过输出结果可以看出这是浅克隆(浅拷贝)
date.setTime(213413412);
System.out.println("v1:"+v1);
System.out.println("v1:hash"+v1.hashCode());
System.out.println("v2:"+v2);
System.out.println("v2:hash"+v2.hashCode());
}
}
//程序输出
v1:VideoProto{name='视频原型', date=Wed Apr 22 10:42:09 CST 2020}
v1:hash1836019240
v2:VideoProto{name='视频原型', date=Wed Apr 22 10:42:09 CST 2020}
v2:hash325040804
通过clone对象修改属性...
v1:VideoProto{name='视频原型', date=Sat Jan 03 19:16:53 CST 1970}
v1:hash1836019240
v2:VideoProto{name='视频原型', date=Sat Jan 03 19:16:53 CST 1970}
v2:hash325040804
深克隆
- 对象是完全不同的两个东西。(除了对象的类型是相同的,对象中的属性是完全的不同的。八竿子打不着的关系)
原型类
package com.tiko.prototype.demo2;
import java.util.Date;
public class VideoProto implements Cloneable {
private String name;
private Date date;
@Override
protected Object clone() throws CloneNotSupportedException {
//实现深克隆
Object clone = super.clone();
//先向下转型为VideoProto
VideoProto v = (VideoProto) clone;
//clone对象的属性值接受被克隆对象的属性值。->完成对象的属性的克隆
v.date = (Date) this.date.clone();//this,指向调用者,即被克隆对象
return v;//返回clone对象
}
public VideoProto() {
}
public VideoProto(String name, Date date) {
this.name = name;
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "VideoProto{" +
"name='" + name + '\'' +
", date=" + date +
'}';
}
}
深克隆实现
@Override
protected Object clone() throws CloneNotSupportedException {
//实现深克隆
Object clone = super.clone();
//先向下转型为VideoProto
VideoProto v = (VideoProto) clone;
//clone对象的属性值接受被克隆对象的属性值。->完成对象的属性的克隆
v.date = (Date) this.date.clone();//this,指向调用者,即被克隆对象
return v;//返回clone对象
}
测试
package com.tiko.prototype.demo2;
import java.util.Date;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//原型对象
Date date = new Date();
VideoProto v1 = new VideoProto("视频原型", date);
System.out.println("v1:"+v1);
System.out.println("v1:hash"+v1.hashCode());
//通过克隆创建新对象
VideoProto v2 = (VideoProto)v1.clone();//克隆出来的对象和原来是一样的
System.out.println("v2:"+v2);
System.out.println("v2:hash"+v2.hashCode());
System.out.println("通过clone对象修改属性...");//通过输出结果可以看出这是深克隆(深拷贝)
date.setTime(213413412);
System.out.println("v1:"+v1);
System.out.println("v1:hash"+v1.hashCode());
System.out.println("v2:"+v2);
System.out.println("v2:hash"+v2.hashCode());
}
}
//结果输出
v1:hash1836019240
v2:VideoProto{name='视频原型', date=Wed Apr 22 10:48:46 CST 2020}
v2:hash325040804
通过clone对象修改属性...
v1:VideoProto{name='视频原型', date=Sat Jan 03 19:16:53 CST 1970}
v1:hash1836019240
v2:VideoProto{name='视频原型', date=Wed Apr 22 10:48:46 CST 2020}
v2:hash325040804
参考自狂神说Java