
在介绍原型模式之前,首先了解Java中的clone()方法. 对象中的本机方法
protected native Object clone() throws CloneNotSupportedException;
但是,该方法不能直接使用,需要两个步骤
①实现Cloneable接口,它是一个标记接口,没有自己的方法.
②重写clone()方法
举个小例子,看看如何使用clone():

写一个具有名称和年龄属性的Teacher类. Teacher类实现了可克隆的接口,并覆盖了clone()方法
public class Teacher implements Cloneable {
String name;
Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
编写一个具有属性名称,年龄,教师的学生Stu类,为每个学生分配一名老师,Stu类实现可克隆的接口,并覆盖clone()方法
public class Stu implements Cloneable {
String name;
Integer age;
Teacher teacher;
public Stu() {
System.out.println("测试clone方法是否调用构造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "Stu{" +
"name='" + name + '\'' +
", age=" + age +
", teacher=" + teacher +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
编写测试类:
public static void main(String [] args){
Teacher t1 = new Teacher();
t1.setAge(32);
t1.setName("wang Teacher");
Stu s1 = new Stu();
s1.setName("xiao ming");
s1.setAge(22);
s1.setTeacher(t1);
System.out.println("复制前的学生1:"+s1);
try {
Stu s2 = (Stu) s1.clone();
s2.setName("da ming");
s2.setAge(24);
Teacher t2 = s2.getTeacher();
t2.setName("zhao Teacher");
t2.setAge(34);
s2.setTeacher(t2);
System.out.println("复制后的学生1:"+s1);
System.out.println("复制后的学生2:"+s2);
System.out.println("teacher的地址"+s1.getTeacher().hashCode());
System.out.println("teacher的地址"+s2.getTeacher().hashCode());
} catch (CloneNotSupportedException e) {
}
}

实验结果:
Connected to the target VM, address: '127.0.0.1:52313', transport: 'socket'
测试clone方法是否调用构造方法
复制前的学生1:Stu{name='xiao ming', age=22, teacher=Teacher{name='wang Teacher', age='32'}}
复制后的学生1:Stu{name='xiao ming', age=22, teacher=Teacher{name='zhao Teacher', age='34'}}
复制后的学生2:Stu{name='da ming', age=24, teacher=Teacher{name='zhao Teacher', age='34'}}
teacher的地址1763847188
teacher的地址1763847188
Disconnected from the target VM, address: '127.0.0.1:52313', transport: 'socket'
Process finished with exit code 0
很明显,当给大名学生分配老师的姓名和年龄时,小名学生的老师也被修改了. 这是由clone()方法的浅表复制引起的. 复制小名学生的姓名和年龄时,相应的存储空间已成功复制到大明. 实际上,已经相应地复制了教师的存储空间,但是复制了相同的引用原型模式,请参见结果中两个教师的地址两者均为1763847188,这两个地址引用了相同的存储空间,因此在修改一个时老师,您可以修改其他老师. 解决方案是在学生类中深度复制并重写clone()方法,
/**
* 调用clone()方法时,student中的name和age复制了空间,teacher也复制了空间,但空间中存的引用值是不会变的,还指向的是原来的引用
*/
@Override
protected Object clone() throws CloneNotSupportedException {
Stu newstudent = (Stu) super.clone();
newstudent.teacher = (Teacher) teacher.clone();
return newstudent;
}
实验结果:
测试clone方法是否调用构造方法
复制前的学生1:Student{name='xiao ming', age='22', teacher=Teacher{name='wang Teacher', age='32'}}
复制后的学生1:Student{name='xiao ming', age='22', teacher=Teacher{name='wang Teacher', age='32'}}
复制后的学生2:Student{name='da ming', age='24', teacher=Teacher{name='zhao Teacher', age='34'}}
teacher的地址1836019240
teacher的地址325040804
Process finished with exit code 0

完成〜
=========================分割线==================
原型模式是设计模式之一原型模式,也是新实现的clone()方法
原型模式可以确定由对象实例创建的对象的类型,并通过复制来创建新对象. 原型模式实际上是从一个对象创建另一个新对象,从而使新对象具有原始对象的特征.
编写个人的个人课程和工作经验课程,然后将其直接复制到新的对象中:
工作班:

public class Work {
String address;
String company;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
@Override
public String toString() {
return "work{" +
"address='" + address + '\'' +
", company='" + company + '\'' +
'}';
}
}
个人班
public class Individual implements Cloneable{
String name;
Integer age;
Work work;
public Individual() {
work = new Work();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
/* public Work getWork() {
return work;
}
public void setWork(Work work) {
this.work = work;
}*/
public void setWork(String address,String company) {
work.address = address;
work.company = company;
}
public void setperson(String name,Integer age){
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Individual{" +
"name='" + name + '\'' +
", age=" + age +
", work=" + work +
'}';
}
@Override
protected Individual clone() throws CloneNotSupportedException {
Individual individual = new Individual();
individual.setperson(this.name,this.age);
individual.setWork(this.work.address,this.work.company);
return individual;
}
}
测试班
public class PrototypeDemo {
/**
* 实现原型模式 实质就是实现clone()方法的深拷贝
* 1.实现cloneable()接口,并重写object的clone()方法
* 2. 在clone()方法中实现拷贝,并返回一个拷贝实体。
*/
public static void main(String [] args) throws CloneNotSupportedException {
Individual individual1 = new Individual();
individual1.setperson("xiaoming",22);
individual1.setWork("beijing","baidu");
System.out.println("个人信息拷贝前individual1"+individual1);
Individual individual2 = individual1.clone();
individual2.setperson("daming",24);
individual2.setWork("hangzhou","ali");
System.out.println("个人信息拷贝后individual1"+individual1);
System.out.println("个人信息拷贝后individual2"+individual2);
}
}```
实验结果
Individual1Individual {姓名='小明',年龄= 22,工作=工作{地址='北京',公司='百度'}},然后复制个人信息
Individual1Individual {姓名='小明',年龄= 22,工作=工作{地址='北京',公司='百度'}}复制了个人信息后
Individual2Individual {姓名='大明',年龄= 24,工作=工作{地址='杭州',公司='阿里'}}
版权声明: 本文的内容由Internet用户自发贡献. 版权归作者所有. 社区不拥有所有权,也不承担任何法律责任. 如果您发现该社区存在涉嫌窃,请发送电子邮件至yqgroup@service.aliyun.com进行举报并提供相关证据. 验证后,社区将立即删除涉嫌侵权的内容.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-177217-1.html
为什么还会失败
因为这包装早改了)