原型模式是一种创建型模式,也是属于创建对象的一种方式,像西游记里面的孙悟空吹猴毛也属于原型模式,克隆出来了一群的猴子猴孙,还有细胞的分裂,spring中的Bean的生命周期好像有一个单例还有个原型,那个原型就是每次请求都复制一个对象出来,官方的定义是:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。在java里面有一个clone的方法是属于Object类的,java里的克隆有浅克隆和深克隆之分,下面通过代码来看看:
浅克隆
package pattern.prototype;
public class Person
implements Cloneable {
public String name;
public String pass;
public String[] arr;
public Person(String name,String pass,String[] arr){
this.name=
name;
this.pass=
pass;
this.arr=
arr;
}
@Override
public Object clone()
throws CloneNotSupportedException {
Person person=(Person)
super.clone();return person;
}
}
package pattern.prototype;
public class Test {
public static void main(String[] args)
throws CloneNotSupportedException {
String[] arr={"hello1","hello2"
};
Person person=
new Person("zj","123"
,arr);
Person p=
(Person)person.clone();
System.out.println(p.name);
System.out.println(p.pass);
p.name="jack"
;
p.pass="666"
;
p.arr[0]="wahaha"
;
for (String favor : p.arr) {
System.out.print(favor + " "
);
}
System.out.println();
for (String favor : person.arr) {
System.out.print(favor + " "
);
}
System.out.println();
}
}
返回结果:
zj
123
wahaha hello2
wahaha hello2
通过上面可以看出来,p中的arr修改了值以后,person中的值也进行了修改,所以这是属于浅克隆,浅克隆,对于被克隆的类中成员变量都是基本数据类型,可以实现了两份数据;被克隆的类中成员变量是对象类型,那么这个成员变量还是原来的引用,修改为新对象的值,旧对象的该对象类型的成员变量还是会变化。
深克隆
package pattern.prototype;
public class Person
implements Cloneable {
public String name;
public String pass;
public String[] arr;
public Person(String name,String pass,String[] arr){
this.name=
name;
this.pass=
pass;
this.arr=
arr;
}
@Override
public Object clone()
throws CloneNotSupportedException {
Person person=(Person)
super.clone();
person.arr=arr.clone();
return person;
}
}
package pattern.prototype;
public class Test {
public static void main(String[] args)
throws CloneNotSupportedException {
String[] arr={"hello1","hello2"
};
Person person=
new Person("zj","123"
,arr);
Person p=
(Person)person.clone();
System.out.println(p.name);
System.out.println(p.pass);
p.name="jack"
;
p.pass="666"
;
p.arr[0]="wahaha"
;
for (String favor : p.arr) {
System.out.print(favor + " "
);
}
System.out.println();
for (String favor : person.arr) {
System.out.print(favor + " "
);
}
System.out.println();
}
}
返回结果:
zj
123
wahaha hello2
hello1 hello2
数组中的两个值的修改是都不会影响的,因为他们属于两个对象,所以上面的是属于深克隆.从新生成了地址。但是重写clone方法实现深克隆比较麻烦,要对所有是对象类型的成员变量,进行重新创建实例,重新赋值; 集合类会更麻烦,比如说ArrayList虽然重写了clone(),但还是浅克隆,实现深克隆需要遍历所有的model,创建实例,重新赋值的。
序列化实现深克隆
package pattern.prototype;
import java.io.*
;
public class Apple
implements,Serializable {
public String name;
public int age;
public Apple(String name,
int age){
this.name=
name;
this.age=
age;
}
public Object deepClone(Object obj) {
ByteArrayOutputStream bos =
new ByteArrayOutputStream();
ObjectOutputStream oos =
null;
ObjectInputStream ois =
null;
try {
oos =
new ObjectOutputStream(bos);
oos.writeObject(obj);
ois =
new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bos.close();
oos.close();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
public static void main(String[] args) {
Apple apple=
new Apple("aaa",18
);
Apple apple1 =
(Apple) apple.deepClone(apple);
System.out.println(apple1==
apple);
}
}
这种方式比较简单,不用写很多的冗余的代码,有利于代码的阅读。
转载于:https://www.cnblogs.com/cleveraboy/p/9738022.html