原型模式分为浅克隆与深克隆,克隆模式简单来说就是克隆对象的属性,不管是深度克隆也好,记住了它也不是和原来对象引用指向同一个hashCode地址。意思即使二者并不是同一个对象。浅克隆只是克隆对象的基本属性。深克隆克隆了基本属性和引用属性。大概了解了思路,我们一起来看看代码。
浅克隆
当前对象内变量无引用时,需要克隆对象状态的需求时,浅克隆完全可以胜任。无需继续new出对象赋值。
public class People implements Cloneable{
private String name;
private int age;
private String home;
public People(String name, int age, String home) {
this.name = name;
this.age = age;
this.home = home;
}
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 String getHome() {
return home;
}
public void setHome(String home) {
this.home = home;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", home='" + home + '\'' +
'}';
}
public People clone() throws CloneNotSupportedException {
return (People) super.clone();
}
}
public class ModeTest {
/**
* 浅克隆: 不用重新初始化对象,动态获取对象运行时的状态
* 可以简化对象的创建过程
*
* @param args
*/
public static void main(String[] args) {
People people = new People("原型", 1, "shanghai");
System.out.println(people.toString());
System.out.println("原型HaseCode: "+ people.hashCode());
People people1 = null;
try {
people1 = people.clone();
System.out.println(people1);
System.out.println("克隆HaseCode: "+ people1.hashCode());
} catch (CloneNotSupportedException e) {
System.out.println(e.getMessage());
}
System.out.println(people == people1);
people.setAge(100);
System.out.println(people1);
}
}
下面来看一下运行结果:
People{name='原型', age=1, home='shanghai'}
原型HaseCode: 356573597
People{name='原型', age=1, home='shanghai'}
克隆HaseCode: 1735600054
false
People{name='原型', age=1, home='shanghai'}
Process finished with exit code 0
可以看出来,对象的状态已经完全克隆下来了,但是引用并不是指向同一个对象。
深克隆
当一个对象内有引用时,浅克隆就显得有些无力了,那现在就需要用到深克隆,通过重写clone方法将引用对象的状态引入进来即可。
public class DeepFood implements Cloneable {
private String name;
@Override
public DeepFood clone() throws CloneNotSupportedException {
return (DeepFood) super.clone();
}
public DeepFood(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "DeepFood{" +
"name='" + name + '\'' +
'}';
}
}
public class DeepPeople implements Serializable ,Cloneable{
private String name;
private int age;
private String home;
private DeepFood deepFood;
public DeepPeople(String name, int age, String home) {
this.name = name;
this.age = age;
this.home = home;
}
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 String getHome() {
return home;
}
public void setHome(String home) {
this.home = home;
}
public DeepFood getDeepFood() {
return deepFood;
}
public void setDeepFood(DeepFood deepFood) {
this.deepFood = deepFood;
}
@Override
public String toString() {
return "DeepPeople{" +
"name='" + name + '\'' +
", age=" + age +
", home='" + home + '\'' +
", deepFood=" + deepFood +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
DeepPeople deepPeople = (DeepPeople) super.clone();
deepPeople.setDeepFood(this.deepFood.clone());
return deepPeople;
}
}
public class DeepModeTest {
public static void main(String[] args) {
// 第一种方式深克隆 通过重写cloneable的clone方法
DeepFood deepFood = new DeepFood("food");
DeepPeople deepPeople = new DeepPeople("深度", 2, "shanghai");
deepPeople.setDeepFood(deepFood);
try {
DeepPeople deepPeople1 = (DeepPeople) deepPeople.clone();
System.out.println(deepPeople1);
System.out.println(deepPeople == deepPeople1);
}catch (CloneNotSupportedException e) {
System.out.println(e.getMessage());
}
}
}
来看下运行结果
DeepPeople{name='深度', age=2, home='shanghai', deepFood=DeepFood{name='food'}}
false
我们可以清楚的看到DeepPeople中通过调用food类的浅克隆方法获取到food类的状态赋值给自身的引用,完成了深克隆。
详细源码下载地址:github.com/Liyinzuo/De…
小结
克隆模式分为浅克隆,实现方法即是继承cloneable类调用父类的克隆方法完成浅克隆,浅克隆的缺点即是无法克隆对象内的引用。而深克隆弥补了浅克隆的缺点,通过重写clone方法将引用对象的状态注入进来完成深克隆。
tips:深浅克隆都只是克隆对象的状态,并不是在jvm中指向同一个对象。
spring运用
<bean id="" class="" scope="prototype"/>
也可以通过注解方式
@Scope("prototype")
以上即是克隆模式的介绍,如果有错误或者不足的地方,欢迎指正。