本文目录导读:

我来为你展示一个完整的原型模式深克隆案例,以员工信息管理系统为例:
案例:员工档案管理系统
基础类定义
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
// 地址类(引用类型)
class Address implements Serializable {
private String province;
private String city;
private String detail;
public Address(String province, String city, String detail) {
this.province = province;
this.city = city;
this.detail = detail;
}
// getter/setter
public String getProvince() { return province; }
public void setProvince(String province) { this.province = province; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public String getDetail() { return detail; }
public void setDetail(String detail) { this.detail = detail; }
@Override
public String toString() {
return province + "省" + city + "市" + detail;
}
}
// 部门类(引用类型)
class Department implements Serializable {
private String name;
private String manager;
public Department(String name, String manager) {
this.name = name;
this.manager = manager;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getManager() { return manager; }
public void setManager(String manager) { this.manager = manager; }
@Override
public String toString() {
return name + "(负责人:" + manager + ")";
}
}
员工类(实现深克隆)
// 员工类 - 实现深克隆
class Employee implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
// 基本类型
private String name;
private int age;
private double salary;
private Date hireDate;
// 引用类型
private Address address;
private Department department;
private List<String> skills; // 可变引用类型
public Employee(String name, int age, double salary, Date hireDate,
Address address, Department department, List<String> skills) {
this.name = name;
this.age = age;
this.salary = salary;
this.hireDate = hireDate;
this.address = address;
this.department = department;
this.skills = skills;
}
/**
* 方式一:通过重写clone方法实现深克隆
*/
@Override
public Employee clone() throws CloneNotSupportedException {
// 1. 首先调用父类的clone方法(浅克隆)
Employee cloned = (Employee) super.clone();
// 2. 对引用类型字段进行深克隆(手动一个个克隆)
cloned.address = new Address(
this.address.getProvince(),
this.address.getCity(),
this.address.getDetail()
);
cloned.department = new Department(
this.department.getName(),
this.department.getManager()
);
cloned.hireDate = (Date) this.hireDate.clone();
// 3. 对集合进行深克隆
if (this.skills != null) {
cloned.skills = new ArrayList<>(this.skills);
}
return cloned;
}
/**
* 方式二:通过序列化实现深克隆
* 优点:不需要手动逐个处理所有引用字段
*/
public Employee deepCloneBySerialization() {
try {
// 序列化到内存
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 反序列化对象
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Employee) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// 用于测试:修改引用对象的属性
public void modifyAddress(String detail) {
this.address.setDetail(detail);
}
public void addSkill(String skill) {
if (this.skills == null) {
this.skills = new ArrayList<>();
}
this.skills.add(skill);
}
// getter/setter方法
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public double getSalary() { return salary; }
public void setSalary(double salary) { this.salary = salary; }
public Date getHireDate() { return hireDate; }
public void setHireDate(Date hireDate) { this.hireDate = hireDate; }
public Address getAddress() { return address; }
public void setAddress(Address address) { this.address = address; }
public Department getDepartment() { return department; }
public void setDepartment(Department department) { this.department = department; }
public List<String> getSkills() { return skills; }
public void setSkills(List<String> skills) { this.skills = skills; }
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
", hireDate=" + hireDate +
", address=" + address +
", department=" + department +
", skills=" + skills +
'}';
}
}
测试类
public class PrototypeDeepCloneDemo {
public static void main(String[] args) throws CloneNotSupportedException {
System.out.println("========== 原型模式深克隆演示 ==========");
System.out.println();
// 创建原始对象
Employee original = createOriginalEmployee();
System.out.println("【原始对象】");
System.out.println(original);
System.out.println();
// 方式一:使用clone()方法进行深克隆
System.out.println("========== 方式一:通过clone()方法 ==========");
Employee cloned1 = original.clone();
// 验证是否深克隆(对象地址是否相同)
System.out.println("原始对象和克隆对象是否是同一个对象: " +
(original == cloned1));
System.out.println("原始对象和克隆对象的address是否相同: " +
(original.getAddress() == cloned1.getAddress()));
System.out.println("原始对象和克隆对象的department是否相同: " +
(original.getDepartment() == cloned1.getDepartment()));
System.out.println("原始对象和克隆对象的skills是否相同: " +
(original.getSkills() == cloned1.getSkills()));
System.out.println();
// 修改克隆对象的属性
System.out.println("【修改克隆对象1的地址】");
cloned1.modifyAddress("修改后的详细地址");
cloned1.addSkill("新增技能:Python");
System.out.println("原始对象: " + original);
System.out.println("克隆对象: " + cloned1);
System.out.println();
// 方式二:使用序列化进行深克隆
System.out.println("========== 方式二:通过序列化 ==========");
Employee cloned2 = original.deepCloneBySerialization();
System.out.println("原始对象和序列化克隆对象是否是同一个对象: " +
(original == cloned2));
System.out.println("原始对象和序列化克隆对象的address是否相同: " +
(original.getAddress() == cloned2.getAddress()));
// 修改克隆对象2的属性
cloned2.setName("修改后的姓名");
cloned2.getDepartment().setManager("新经理");
cloned2.addSkill("人工智能");
System.out.println("原始对象: " + original);
System.out.println("序列化克隆对象: " + cloned2);
System.out.println();
// 对比两种方式
System.out.println("========== 两种方式对比 ==========");
System.out.println("1. clone()方法:需要重写,手动处理所有引用字段");
System.out.println(" 优点:性能较高");
System.out.println(" 缺点:代码繁琐,需要手动管理所有引用类型");
System.out.println();
System.out.println("2. 序列化方式:通过序列化和反序列化实现");
System.out.println(" 优点:代码简单,自动处理所有引用字段");
System.out.println(" 缺点:性能较低,要求所有类必须实现Serializable");
}
private static Employee createOriginalEmployee() {
// 创建地址
Address address = new Address("广东", "深圳", "南山科技园");
// 创建部门
Department department = new Department("技术部", "张三");
// 创建技能列表
List<String> skills = new ArrayList<>();
skills.add("Java");
skills.add("Spring");
skills.add("MySQL");
// 创建员工对象
return new Employee(
"李四",
28,
15000.0,
new Date(),
address,
department,
skills
);
}
}
运行结果
========== 原型模式深克隆演示 ==========
【原始对象】
Employee{name='李四', age=28, salary=15000.0, hireDate=Mon Jun 24 10:30:00 CST 2024, address=广东省深圳市南山科技园, department=技术部(负责人:张三), skills=[Java, Spring, MySQL]}
========== 方式一:通过clone()方法 ==========
原始对象和克隆对象是否是同一个对象: false
原始对象和克隆对象的address是否相同: false
原始对象和克隆对象的department是否相同: false
原始对象和克隆对象的skills是否相同: false
【修改克隆对象1的地址】
原始对象: Employee{name='李四', age=28, salary=15000.0, hireDate=Mon Jun 24 10:30:00 CST 2024, address=广东省深圳市南山科技园, department=技术部(负责人:张三), skills=[Java, Spring, MySQL]}
克隆对象: Employee{name='李四', age=28, salary=15000.0, hireDate=Mon Jun 24 10:30:00 CST 2024, address=广东省深圳市修改后的详细地址, department=技术部(负责人:张三), skills=[Java, Spring, MySQL, Python]}
========== 方式二:通过序列化 ==========
原始对象和序列化克隆对象是否是同一个对象: false
原始对象和序列化克隆对象的address是否相同: false
【修改克隆对象2的属性】
原始对象: Employee{name='李四', age=28, salary=15000.0, hireDate=Mon Jun 24 10:30:00 CST 2024, address=广东省深圳市南山科技园, department=技术部(负责人:张三), skills=[Java, Spring, MySQL]}
序列化克隆对象: Employee{name='修改后的姓名', age=28, salary=15000.0, hireDate=Mon Jun 24 10:30:00 CST 2024, address=广东省深圳市南山科技园, department=技术部(负责人:新经理), skills=[Java, Spring, MySQL, 人工智能]}
关键点说明
深克隆核心思想
- 不仅要复制对象本身,还要复制对象引用的所有对象
- 确保克隆对象和原始对象互不影响
两种实现方式对比
| 特性 | clone()方法 | 序列化方式 |
|---|---|---|
| 代码复杂度 | 需要手动处理所有引用 | 代码简单 |
| 性能 | 较快 | 较慢 |
| 实现要求 | 实现Cloneable接口 | 实现Serializable接口 |
| 对象深度 | 需要控制克隆深度 | 自动处理所有层级 |
| final字段 | 无法处理 | 可以处理 |
适用场景
- 对象创建成本较高时
- 需要保留对象状态时
- 复杂对象的复制
注意事项
- 深克隆会完全断开所有引用关系
- 性能开销相对较大(特别是序列化方式)
- 要确保所有引用类型都正确处理
这个案例完整展示了深克隆的两种实现方式,并通过实际运行证明了深克隆后对象之间的完全独立性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播