import java.util.Date;
public class Pig implements Cloneable {
private String name;
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Pig{" +
"name='" + name + '\'' +
", birthday=" + birthday +
'}'+ super.toString();
}
}
调用
import java.util.Date;
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Pig pig1 = new Pig();
pig1.setName("佩奇");
pig1.setBirthday(new Date(0L));
System.out.println("【原始】pig1=" + pig1);
Pig pig2 = (Pig) pig1.clone();
System.out.println("【原始】pig2="+ pig2);
// 调整pig1的属性值
pig1.setName("哼哼");
pig1.getBirthday().setTime(66666666666L);
System.out.println("【变更】pig1=" + pig1);
System.out.println("【变更】pig2=" + pig2);
}
}
运行结果
我们在Main函数中之改变了pig1的生日属性,但从结果中可以看出pig2也跟着发生了变化,但是名称属性,并未跟着发生变化,由此说明,浅克隆只能使当前对象中值类型变量保持独立性,如要引用类型也保持独立性,则需要深克隆才可以
深克隆
import java.util.Date;
public class Pig implements Cloneable {
private String name;
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// 深克隆
Pig pig = (Pig)super.clone();
// 将对象中引用变量也执行一下clone()方法
pig.birthday = (Date) pig.birthday.clone();
return pig;
}
@Override
public String toString() {
return "Pig{" +
"name='" + name + '\'' +
", birthday=" + birthday +
'}'+ super.toString();
}
}
运行结果
这里必要的提一点,原型模式和单例模式,似乎存在一丢丢的矛盾点,那就是单例模式的类来实现Cloneable接口,这样单例模式就会失效,由此,需要特殊的针对该点做下调整,改进后的单例模式代码如下
单例模式改进版
public class Singleton implements Cloneable {
private final static Singleton instance;
static{
instance = new Singleton();
}
private Singleton(){
}
private static Singleton getInstance(){
return instance;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// 注释掉一下代码,直接调用getInstance()方法,来屏蔽克隆带来的破坏性,保持单例的唯一性
// return super.clone();
return getInstance();
}
}