实现原型模式需要实现标记性接口Cloneable 。
一般会重写clone()方法,如果只重写clone()方法而没有实现接口,调用是会抛异常。
一般用于一个对象的属性已经确定,需要产生许多相同对象的时候。
注意区分浅克隆和深克隆。
/**
* 浅克隆
*/
public class Test {
public static void main(String[] args) throws Exception {
Person p1 = new Person();
Person p2 = (Person)p1.clone();
System.out.println(p2.age + " " + p2.score);
System.out.println(p2.loc);
//true 因为Location并没有克隆,还是指向同一个
System.out.println(p1.loc == p2.loc);
p1.loc.street = "sh";
System.out.println(p2.loc);//p1的Location属性的改变会影响p2
}
}
class Person implements Cloneable {
int age = 8;
int score = 100;
Location loc = new Location("bj", 22);
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Location {
String street;
int roomNo;
@Override
public String toString() {
return "Location{" +
"street='" + street + '\'' +
", roomNo=" + roomNo +
'}';
}
public Location(String street, int roomNo) {
this.street = street;
this.roomNo = roomNo;
}
}
/**
* 深克隆
*/
public class Test {
public static void main(String[] args) throws Exception {
Person p1 = new Person();
Person p2 = (Person)p1.clone();
System.out.println(p2.age + " " + p2.score);
System.out.println(p2.loc);
//false 因为Location也克隆了,不在指向同一个
System.out.println(p1.loc == p2.loc);
p1.loc.street = "sh";
System.out.println(p2.loc);//p1的Location属性的改变不会影响p2
}
}
class Person implements Cloneable {
int age = 8;
int score = 100;
Location loc = new Location("bj", 22);
@Override
public Object clone() throws CloneNotSupportedException {
Person p = (Person)super.clone();
p.loc = (Location)loc.clone();
return p;
}
}
class Location implements Cloneable {
String street;
int roomNo;
@Override
public String toString() {
return "Location{" +
"street='" + street + '\'' +
", roomNo=" + roomNo +
'}';
}
public Location(String street, int roomNo) {
this.street = street;
this.roomNo = roomNo;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}