让我们来看一个例子:
设计一个客户类Customer,其中客户地址存储在地址类Address中,用浅克隆和深克隆分别实现Customer对象的复制并比较这两种克隆方式的异同。
代码实现
Customer类和Address类都是实现的Java 内置的 java.lang.Cloneable
接口,无需自己定义
1. Customer 类
package experiment05.二;
public class Customer implements Cloneable {
private String name;
private int age;
private Address address;
// 构造方法接受 CustomerBuilder 参数
public Customer(CustomerBuilder builder) {
this.name = builder.getName();
this.age = builder.getAge();
this.address = builder.getAddress();
}
// 浅克隆
@Override
public Customer clone() throws CloneNotSupportedException {
return (Customer) super.clone();
}
// 深克隆
public Customer deepClone() throws CloneNotSupportedException {
Customer cloned = (Customer) super.clone();
cloned.address = this.address.clone();
return cloned;
}
// Getter 方法
public Address getAddress() {
return address;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
2. CustomerBuilder 类
package experiment05.二;
public class CustomerBuilder {
private String name;
private int age;
private Address address;
public CustomerBuilder withName(String name) {
this.name = name;
return this;
}
public CustomerBuilder withAge(int age) {
this.age = age;
return this;
}
public CustomerBuilder withAddress(Address address) {
this.address = address;
return this;
}
public Customer build() {
return new Customer(this);
}
// 提供给 Customer 构造方法访问的 Getter
String getName() {
return name;
}
int getAge() {
return age;
}
Address getAddress() {
return address;
}
}
3.Address 类
package experiment05.二;
public class Address implements Cloneable {
private String street;
private String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
@Override
public Address clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
public void setStreet(String street) {
this.street = street;
}
public String getStreet() {
return street;
}
public String getCity() {
return city;
}
}
4. Main 类
package experiment05.二;
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
// 使用独立建造者类创建对象(链式写法)
Customer original = new CustomerBuilder()
.withName("张三")
.withAge(30)
.withAddress(new Address("人民路123号", "北京市"))
//以上三个的编译类型和运行类型都是CustomerBuilder
.build();
// 只有这个返回的是Customer对象(Customer的编译运行类型),build()方法实际返回的是new Customer(...)对象
/**
* 编译类型由变量声明或方法返回类型决定
* 运行类型由实际创建的对象决定
*/
/* ==等效于==
步骤1:创建建造者对象
CustomerBuilder builder1 = new CustomerBuilder(); // ✅ 编译类型=运行类型=CustomerBuilder
步骤2:设置姓名(返回建造者)
CustomerBuilder builder2 = builder1.withName("张三"); // ✅ 编译类型=运行类型=CustomerBuilder
步骤3:设置年龄(返回建造者)
CustomerBuilder builder3 = builder2.withAge(30); // ✅ 编译类型=运行类型=CustomerBuilder
步骤4:设置地址(返回建造者)
CustomerBuilder builder4 = builder3.withAddress(new Address("人民路123号", "北京市")); // ✅ 类型同上
步骤5:构建最终对象
Customer original = builder4.build(); // ✅ 编译类型=Customer | 运行类型=Customer
*/
// 浅克隆和深克隆
Customer shallowCopy = original.clone();
Customer deepCopy = original.deepClone();
// 修改原对象地址
original.getAddress().setStreet("长安街456号");
// 验证结果
System.out.println("原始对象地址: " + original.getAddress().getStreet()); // 长安街456号
System.out.println("浅克隆对象地址: " + shallowCopy.getAddress().getStreet()); // 长安街456号
System.out.println("深克隆对象地址: " + deepCopy.getAddress().getStreet()); // 人民路123号
}
}
简单版 (无建造者)
class Address implements Cloneable {
private String street;
private String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
@Override
public Address clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
public void setStreet(String street) {
this.street = street;
}
public String getStreet() {
return street;
}
}
class Customer implements Cloneable {
private String name;
private int age;
private Address address;
// 直接使用构造方法初始化
public Customer(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
// 浅克隆
@Override
public Customer clone() throws CloneNotSupportedException {
return (Customer) super.clone();
}
// 深克隆
public Customer deepClone() throws CloneNotSupportedException {
Customer cloned = (Customer) super.clone();
cloned.address = this.address.clone();
return cloned;
}
public Address getAddress() {
return address;
}
public String getName() {
return name;
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
// 直接使用构造方法创建对象
Customer original = new Customer("张三", 30, new Address("人民路123号", "北京市"));
Customer shallowCopy = original.clone();
Customer deepCopy = original.deepClone();
original.getAddress().setStreet("长安街456号");
System.out.println("原始对象地址: " + original.getAddress().getStreet()); // 长安街456号
System.out.println("浅克隆对象地址: " + shallowCopy.getAddress().getStreet()); // 长安街456号
System.out.println("深克隆对象地址: " + deepCopy.getAddress().getStreet()); // 人民路123号
}
}