原型模式核心复制,每次new出来的对象完全不一样,实现对象之间的隔离。 学习前最好先掌握jAVA值传递和深浅拷贝
设计模式,一定要敲代码理解
浅拷贝
克隆出对象,其中两者的引用类型属性是同一个对象。
对象信息
/**
* @author ggbond
* @date 2024年04月03日 08:38
*/
public class Mankind01 implements Cloneable {
private int age;
private Date birth;
public Mankind01(int age, Date birth){
this.age=age;
this.birth=birth;
}
public int getAge() {
return age;
}
public Date getBirth() {
return birth;
}
public void setAge(int age) {
this.age = age;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
protected Mankind01 clone() throws CloneNotSupportedException {
return (Mankind01) super.clone();
}
}
测试
/**
* @author ggbond
* @date 2024年04月03日 08:42
*
*/
public class test01 {
public static void main(String[] args) throws Exception {
Date birth=new Date(2022,4,3);
int age=25;
Mankind01 m1=new Mankind01(age,birth);
Mankind01 m2=m1.clone();
System.out.println("m1.age:"+m1.getAge()+" "+"m2.age:"+m2.getAge());
System.out.println("m1.birth:"+m1.getBirth()+" "+"m2.birth:"+m2.getBirth());
System.out.println("-----------");
age=21; birth.setTime(1232321321L);
System.out.println(m1.getBirth() == m2.getBirth()); // true
System.out.println("m1.age:"+m1.getAge()+" "+"m2.age:"+m2.getAge());
System.out.println("m1.birth:"+m1.getBirth()+" "+"m2.birth:"+m2.getBirth());
}
}
测试结果发现, m1,m2 中的属性 引用类型 Date birth 是指向同一个对象
m1.age:25 m2.age:25
m1.birth:Wed May 03 00:00:00 CST 3922 m2.birth:Wed May 03 00:00:00 CST 3922
-----------
true
m1.age:25 m2.age:25
m1.birth:Thu Jan 15 14:18:41 CST 1970 m2.birth:Thu Jan 15 14:18:41 CST 1970
深拷贝
对象信息
/**
* @author ggbond
* @date 2024年04月03日 08:38
*/
public class Mankind02 implements Cloneable {
private int age;
private Date birth;
public Mankind02(int age, Date birth){
this.age=age;
this.birth=birth;
}
public int getAge() {
return age;
}
public Date getBirth() {
return birth;
}
public void setAge(int age) {
this.age = age;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
protected Mankind02 clone() throws CloneNotSupportedException {
Mankind02 m = (Mankind02) super.clone();
m.setBirth((Date) birth.clone());
return m;
}
}
测试
/**
* @author ggbond
* @date 2024年04月03日 08:42
* 原型模式,本质是克隆复制对象。
*/
public class test02 {
public static void main(String[] args) throws Exception {
Date birth=new Date(2022,4,3);
int age=25;
Mankind02 m1=new Mankind02(age,birth);
Mankind02 m2=m1.clone();
System.out.println("m1.age:"+m1.getAge()+" "+"m2.age:"+m2.getAge());
System.out.println("m1.birth:"+m1.getBirth()+" "+"m2.birth:"+m2.getBirth());
System.out.println("-----------");
age=21; birth.setTime(123232321L);
System.out.println(m1.getBirth() == m2.getBirth()); // true
System.out.println("m1.age:"+m1.getAge()+" "+"m2.age:"+m2.getAge());
System.out.println("m1.birth:"+m1.getBirth()+" "+"m2.birth:"+m2.getBirth());
}
}
结果
m1.age:25 m2.age:25
m1.birth:Wed May 03 00:00:00 CST 3922 m2.birth:Wed May 03 00:00:00 CST 3922
-----------
false
m1.age:25 m2.age:25
m1.birth:Fri Jan 02 18:13:52 CST 1970 m2.birth:Wed May 03 00:00:00 CST 3922
总结
使用场景:需要到大量相同对象,但内部内容或结构可能进行修改。思考上述被复制对象中如果含多层引用,克隆包含循环引用的复杂对象可能会非常麻烦。
代码下载
代码下载