简介
当要创建的对象的类型由一个原型实例确定时,将使用该实例进行克隆以生成新对象。不需要知道任何创建细节,不调用构造函数,可以在运行时来创建对象,可以动态加载类。该模式属于创建型模式。
适用场景
1、类初始化的时候会消耗大量的资源
2、new一个对象需要很多繁琐的步骤
3、构造函数比较复杂
4、在循环中创建大量的类时
优点
1、性能要比使用new高
2、简化了创建对象的过程
3、创建一个新的对象
缺点
1、必须要重写克隆方法(clone())
2、对复杂对象进行克隆会引入风险
3、深拷贝、浅拷贝使用要注意
代码示例
public class Horse implements Cloneable {
private String color;
private Date age;
public Horse(String color, Date age) {
this.color = color;
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Date getAge() {
return age;
}
public void setAge(Date age) {
this.age = age;
}
@Override
public String toString() {
return "Horse{" +
"color='" + color + '\'' +
", age=" + age +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
主要是实现Cloneable接口,然后重写clone()方法,测试类:
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
Date now = new Date();
Horse horse = new Horse("白色",now);
Horse horse2 = (Horse) horse.clone();
System.out.println(horse);
System.out.println(horse2);
}
}
输出为
把代码修改为如下
public static void main(String[] args) throws CloneNotSupportedException {
Date now = new Date();
Horse horse = new Horse("白色",now);
Horse horse2 = (Horse) horse.clone();
horse.getAge().setTime(444444444444L);
System.out.println(horse);
System.out.println(horse2);
}
输出结果
本来只是想对horse的年龄进行修改,但是horse2也被修改掉了,这个其实是浅克隆,如果你需要只修改horse的值,horse2的值不变,那么可以修改为:
@Override
protected Object clone() throws CloneNotSupportedException {
Horse horse = (Horse) super.clone();
//对时间进行深克隆
horse.age = (Date) horse.age.clone();
return horse;
}
所以在使用原型模式的时候,需要小心,有可能一不小心就出问题了。
上面示例源码
源码分析
jdk中应用
ArrayList、HashMap
如图都使用了原型模式。
mybatis中应用
在很多源码中都大量使用了原型模式。
本文为博主原创文章,未经博主允许不得转载。
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载