发布于2021-03-13 13:29 阅读(1172) 评论(0) 点赞(18) 收藏(3)
原型模式属于创建型。用于创建拷贝复杂对象,避免重复创建对象发生的资源损耗,在一定程度上提升了性能。原型模式主要被分为浅拷贝和深拷贝2种模式,它主要实现了接口Cloneable
,重写Object
类中的clone
方法。
浅拷贝只能对基本类型(long,double,float,int,short,byte,boolean,char)和String
类型有效果,对复杂的类型只能不能有效果。
public class Car implements Cloneable{
private String model;
private int wheelRadius;
private boolean autoSeat;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
测试
@Test
public void testCloneable() throws CloneNotSupportedException {
Car car = new Car().setModel("运动版").setAutoSeat(true).setWheelRadius(19);
Car cloneCar1 = (Car) car.clone();
cloneCar1.setModel("标准版");
Car cloneCar2 = (Car) car.clone();
cloneCar2.setAutoSeat(false);
Car cloneCar3 = (Car) car.clone();
cloneCar3.setWheelRadius(18);
Car cloneCar4 = (Car) car.clone();
log.info("car: {}",car);
log.info("cloneCar1: {}",cloneCar1);
log.info("cloneCar2: {}",cloneCar2);
log.info("cloneCar3: {}",cloneCar3);
log.info("cloneCar4: {}",cloneCar4);
}
2021-03-11 14:26:14.077 INFO 104540 --- [ main] org.example.singleton.PrototypeTest : car: Car(super=org.example.prototype.Car@3afee9e3, model=运动版, wheelRadius=19, autoSeat=true)
2021-03-11 14:26:14.079 INFO 104540 --- [ main] org.example.singleton.PrototypeTest : cloneCar1: Car(super=org.example.prototype.Car@4abc50d4, model=标准版, wheelRadius=19, autoSeat=true)
2021-03-11 14:26:14.080 INFO 104540 --- [ main] org.example.singleton.PrototypeTest : cloneCar2: Car(super=org.example.prototype.Car@3afee9f5, model=运动版, wheelRadius=19, autoSeat=false)
2021-03-11 14:26:14.080 INFO 104540 --- [ main] org.example.singleton.PrototypeTest : cloneCar3: Car(super=org.example.prototype.Car@3afee9a8, model=运动版, wheelRadius=18, autoSeat=true)
2021-03-11 14:26:14.080 INFO 104540 --- [ main] org.example.singleton.PrototypeTest : cloneCar4: Car(super=org.example.prototype.Car@3afee9e3, model=运动版, wheelRadius=19, autoSeat=true)
Car
类设置了3种数据类型,分别对3种类型进行测试,从测试日志和代码可以看到,当从car
对象克隆出的cloneCar4
没有对其属性进行更改,则拷贝出的对象与原对象相同,当修改其中一个属性后,对象的引用地址发生变化。
当将上面的代码改造一下
添加一个Wheel
类
public class Wheel {
private int wheelRadius;
}
改造后的Car
类
public class Car implements Cloneable{
private String model;
private int wheelRadius;
private boolean autoSeat;
private Wheel wheel;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
测试代码
@Test
public void testSimpleCloneable() throws CloneNotSupportedException {
Car car = new Car().setModel("运动版").setAutoSeat(true).setWheelRadius(19).setWheel(new Wheel().setWheelRadius(19));
Car cloneCar1 = (Car) car.clone();
cloneCar1.getWheel().setWheelRadius(18);
log.info("car: {}",car);
log.info("cloneCar1: {}",cloneCar1);
}
测试日志
2021-03-11 14:44:58.714 INFO 104856 --- [ main] org.example.singleton.PrototypeTest : car: Car(super=org.example.prototype.Car@98bfe79e, model=运动版, wheelRadius=19, autoSeat=true, wheel=Wheel(super=org.example.prototype.Wheel@4d, wheelRadius=18))
2021-03-11 14:44:58.717 INFO 104856 --- [ main] org.example.singleton.PrototypeTest : cloneCar1: Car(super=org.example.prototype.Car@98bfe79e, model=运动版, wheelRadius=19, autoSeat=true, wheel=Wheel(super=org.example.prototype.Wheel@4d, wheelRadius=18))
可以发现,car
对象初始化时,wheel
属性中的wheelRadius
=19,当克隆出cloneCar1
对象后,并且设置wheel
属性中的wheelRadius
=18后,不仅cloneCar1
对象没有变化,还影响了原有对象的属性值,由此可见,当对象中存在某个复杂类型的对象时,浅拷贝并不适合使用。
当对象中存在复杂类型的对象时,包括数组、集合和其他自定义的类,应该使用深拷贝。
改造Wheel
类,让它也实现Cloneable
接口
public class Wheel implements Cloneable{
private int wheelRadius;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
改造Car
类的clone
方法
@Override
public Object clone() throws CloneNotSupportedException {
Car car = (Car) super.clone();
Wheel wheel = (Wheel) this.wheel.clone();
car.setWheel(wheel);
return car;
}
测试代码
@Test
public void testDeepCloneable() throws CloneNotSupportedException {
Car car = new Car().setModel("运动版").setAutoSeat(true).setWheelRadius(19).setWheel(new Wheel().setWheelRadius(19));
Car cloneCar1 = (Car) car.clone();
cloneCar1.getWheel().setWheelRadius(18);
log.info("car: {}",car);
log.info("cloneCar1: {}",cloneCar1);
}
日志信息
2021-03-11 15:16:04.530 INFO 104668 --- [ main] org.example.singleton.PrototypeTest : car: Car(super=org.example.prototype.Car@98bfe79f, model=运动版, wheelRadius=19, autoSeat=true, wheel=Wheel(super=org.example.prototype.Wheel@4e, wheelRadius=19))
2021-03-11 15:16:04.533 INFO 104668 --- [ main] org.example.singleton.PrototypeTest : cloneCar1: Car(super=org.example.prototype.Car@98bfe79e, model=运动版, wheelRadius=19, autoSeat=true, wheel=Wheel(super=org.example.prototype.Wheel@4d, wheelRadius=18))
从日志信息中查看到,重写clone
方法后,car
对象中的自定义类型拷贝成功,并不影响原对象。
原文链接:https://blog.csdn.net/u010659671/article/details/114668183
作者:忽明忽灭
链接:http://www.javaheidong.com/blog/article/114223/d8bf72623683923d88a3/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!