Java设计模式【之】原型模式-浅拷贝【场景:克隆羊】
1.原型模式(Prototype)
实现方式:
需要被克隆的class类, 重写Object中的
clone()
方法,并实现Cloneable
接口(否则报错 CloneNotSupportedException)注意:
1.被克隆对象.clone()出的对象,是被克隆对象的当前状态。
2.被克隆对象 如果使用的是默认实现super.clone();
此时属于浅拷贝。特点
1.创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率。
2.不用重新初始化对象,而是动态地获得对象运行时的状态。
3.在实现深克隆的时候可能需要比较复杂的代码。
4.实现深拷贝是,推荐序列化方式。
浅拷贝
- 浅拷贝
- 1.成员变量是,基本数据类型,此时浅拷贝是值传递。
其中一个对象的值修改后,不会影响到另一个对象的值。- 2.成员变量是,引用数据类型,比如:数组、类的对象。
此时浅拷贝是引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。
两个对象中的该成员变量执行的是同一个地址,其中一个对象的值修改后,另一个对象的值也会改变。
深拷贝
- 深拷贝
- 1.复制对象的所有基本数据类型的成员变量值
- 2.为所有引用数据类型的成员变量申请存储空间,直到该对象可达的所有对象,递归式完全克隆
- 3.深拷贝实现方式
1.重写clone方法来实现深拷贝
2.通过对象序列化实现深拷贝(推荐)
2.代码实现(浅拷贝)
2.1.羊.class
public class Yang_浅 implements Cloneable {
public String name;
public int age;
public ArrayList<String> list;
public Yang_浅(String name, int age) {
this.name = name;
this.age = age;
this.list = new ArrayList<>();
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
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 void add() {
this.list.add(" MMM ");
}
}
2.2.测试类.class
- 注意控制台输出
在这里插入代码片
内容:浅拷贝导致,虽然只是更改了其中一只羊的数组,但是两只羊的数组内容都发生了变化
/**
* 原型模式(Prototype)
* 实现方式:
* 需要被克隆的 class类, 重写Object中的clone()方法,并实现Cloneable接口(否则报错 CloneNotSupportedException)
* 注意:
* 1.被克隆对象.clone()出的对象,是被克隆对象的当前状态
* 2.被克隆对象 如果返回的值是 super.clone(); 此时属于浅拷贝
* <p>
* 浅拷贝
* 1)成员变量是,基本数据类型,此时浅拷贝是值传递。其中一个对象的值修改后,不会影响到另一个对象的值。
* 2)成员变量是,引用数据类型,比如:数组、类的对象。此时浅拷贝是引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。两个对象中的该成员变量执行的是同一个地址,其中一个对象的值修改后,另一个对象的值也会改变。
*/
public class _Test_浅 {
public static void main(String[] args) throws CloneNotSupportedException {
//
Yang_浅 yang = new Yang_浅("001", 1);
System.out.println("原始羊-姓名:" + yang.name);
System.out.println("原始羊-地址:" + yang);
System.out.println();
//
Yang_浅 clone_yang = (Yang_浅) yang.clone();
System.out.println("克隆羊-地址:" + clone_yang);
System.out.println("克隆羊-姓名:" + clone_yang.name);
System.out.println();
//
System.out.println("修改原始羊姓名为:小明");
yang.setName("小明");
System.out.println();
//
System.out.println("原始羊-姓名:" + yang.name);
System.out.println("克隆羊-姓名:" + clone_yang.name);
System.out.println();
//
System.out.println("原始羊-数组内容:" + yang.list);
System.out.println("克隆羊-数组内容:" + clone_yang.list);
System.out.println();
//
System.out.println("原始羊数组添加内容 MMM ");
yang.add();
System.out.println();
//
System.out.println("原始羊-数组内容:" + yang.list);
System.out.println("克隆羊-数组内容:" + clone_yang.list);
System.out.println();
}
}
2.3.输出内容
原始羊-姓名:001
原始羊-地址:com.sjms._04_原型.Yang_浅@4d7e1886
克隆羊-地址:com.sjms._04_原型.Yang_浅@3cd1a2f1
克隆羊-姓名:001
修改原始羊姓名为:小明
原始羊-姓名:小明
克隆羊-姓名:001
原始羊-数组内容:[]
克隆羊-数组内容:[]
原始羊数组添加内容 MMM
原始羊-数组内容:[ MMM ]
克隆羊-数组内容:[ MMM ]
3.源码下载
《七大设计原则》
《目录:Java设计模式》
《幕》
- 《清平调—李白》
- 云想衣裳花想容,春风拂面露华浓。
- 若非群玉山头见,会向瑶台月下逢。
- ~ 今 ~ ❀ ~ ❀❀❀❀❀❀❀❀❀❀ ❀❀❀❀❀❀❀❀❀❀ ❀❀❀❀❀❀❀