模式定义:原型模式指定创建对象的种类,并且通过拷贝这些原型创建新的对象。(用于对象的复制)
两个步骤:
Student:
//1、实现Cloneable接口
public class Student implements Cloneable{
private Integer id;
private String name;
private String age;
public Student(Integer id,String name,String age){
this.id = id;
this.name = name;
this.age = age;
}
//生成getter() 和 setter() 方法
//2、重写clone()方法
@Override
protected Student clone() throws CloneNotSupportedException {
return (Student)super.clone();
}
@Override
public String toString() {
return super.hashCode() + " " +"Student{" +
"id=" + id +
", name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
test:
public class test1 {
public static void main(String[] args) throws CloneNotSupportedException {
Student student = new Student(1,"chenl","12");
Student student1 = student.clone();
Student student2 = student.clone();
System.out.println(student1.toString());
System.out.println(student2.toString());
}
}
但是,其对引用类型的拷贝则是浅拷贝(即拷贝引用,或者说拷贝地址值),下面是验证方法:
新建一个IDCard :
public class IDCard{
private Integer id;
private String Number;
public IDCard(Integer id,String Number){
this.id = id;
this.Number = Number;
}
//生成getter()和 setter()方法
@Override
public String toString() {
return super.hashCode()+ " " + "IDCard{" +
"id=" + id +
", Number='" + Number + '\'' +
'}';
}
}
更改Student :
class Student implements Cloneable{
private Integer id;
private String name;
private String age;
private IDCard idCard;
public Student(Integer id,String name,String age,IDCard idCard){
this.id = id;
this.name = name;
this.age = age;
this.idCard = idCard;
}
//生成getter() 和 setter()方法
@Override
protected Student clone() throws CloneNotSupportedException {
return (Student)super.clone();
}
@Override
public String toString() {
return super.hashCode() + " " +"Student{" +
"id=" + id +
", name='" + name + '\'' +
", age='" + age + '\'' +
", idCard=" + idCard +
'}';
}
}
测试类:
public class test1 {
public static void main(String[] args) throws CloneNotSupportedException {
IDCard idCard = new IDCard(1,"123");
Student student = new Student(1,"chenl","12",idCard);
Student student1 = student.clone();
Student student2 = student.clone();
System.out.println(student1.toString());
System.out.println(student2.toString());
idCard.setNumber("456");
System.out.println(student);
System.out.println(student1.toString());
System.out.println(student2.toString());
}
}
可以看出,student1和student2对象IDCard的Number值随着Student对象IDCard的值改变而改变,说明它们引用了同一个对象。
如果想要实现深拷贝,则需要在IDCard类上实现Cloneable接口并重写clone()方法。
更改IDCard:
//1、实现Cloneale接口
public class IDCard implements Cloneable{
private Integer id;
private String Number;
public IDCard(Integer id,String Number){
this.id = id;
this.Number = Number;
}
//生成getter() 和 setter()方法
//2、重写clone()方法
@Override
protected IDCard clone() throws CloneNotSupportedException {
return (IDCard) super.clone();
}
@Override
public String toString() {
return super.hashCode()+ " " + "IDCard{" +
"id=" + id +
", Number='" + Number + '\'' +
'}';
}
}
更改Student:
class Student implements Cloneable{
private Integer id;
private String name;
private String age;
private IDCard idCard;
public Student(Integer id,String name,String age,IDCard idCard){
this.id = id;
this.name = name;
this.age = age;
this.idCard = idCard;
}
//生成getter() 和 setter()方法
//重写clone()方法
@Override
protected Student clone() throws CloneNotSupportedException {
Student student = (Student) super.clone();
student.setIdCard(student.getIdCard().clone());
return student;
}
@Override
public String toString() {
return super.hashCode() + " " +"Student{" +
"id=" + id +
", name='" + name + '\'' +
", age='" + age + '\'' +
", idCard=" + idCard +
'}';
}
}
测试:
public class test1 {
public static void main(String[] args) throws CloneNotSupportedException {
IDCard idCard = new IDCard(1,"123");
Student student = new Student(1,"chenl","12",idCard);
Student student1 = student.clone();
Student student2 = student.clone();
idCard.setNumber("456");
System.out.println(student);
System.out.println(student1.toString());
System.out.println(student2.toString());
idCard.setNumber("456");
System.out.println(student);
System.out.println(student1.toString());
System.out.println(student2.toString());
}
}
如图,即使改变了idCard的 Number值,student1 和 student2的对应值并未发生改变,说明它们单独拷贝了一份数据。