在 Java 中,当你实现 clone()
方法时,通常会调用 super.clone()
来确保正确地复制对象。super.clone()
调用 Object
类的 clone()
方法,这个方法进行的是浅复制,它复制对象中的所有字段,包括基本类型和对象引用,但不复制引用对象本身。以下是 clone()
方法实现的详细说明和示例代码。
- 实现
Cloneable
接口:类必须实现Cloneable
接口,否则super.clone()
会抛出CloneNotSupportedException
异常。 - 调用
super.clone()
:确保父类的字段也被正确复制。 - 处理
CloneNotSupportedException
异常:需要捕获和处理这个异常。
class Person implements Cloneable {
private String name;
private int age;
private Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// 调用 super.clone() 进行浅复制
Person cloned = (Person) super.clone();
// 深复制:如果成员变量是对象且需要深复制,需手动克隆这些对象
cloned.address = (Address) this.address.clone();
return cloned;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", address=" + address + '}';
}
}
class Address implements Cloneable {
private String city;
private String street;
public Address(String city, String street) {
this.city = city;
this.street = street;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Address{city='" + city + "', street='" + street + "'}";
}
}
public class Main {
public static void main(String[] args) {
try {
Address address = new Address("New York", "5th Avenue");
Person person1 = new Person("John Doe", 30, address);
Person person2 = (Person) person1.clone();
// 修改原始对象的地址
person1.address.street = "Broadway";
System.out.println(person1);
System.out.println(person2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
说明
- 实现
Cloneable
接口:Person
类和Address
类都实现了Cloneable
接口。 - 调用
super.clone()
:在Person
和Address
类的clone()
方法中,调用了super.clone()
以执行默认的浅复制。 - 深复制:在
Person
类中,我们手动克隆了address
字段,这是一种深复制的实现方式,以确保Person
对象的address
字段是一个新的对象,而不是引用原对象的address
字段。
在这个示例中,通过修改 person1
的地址字段,可以看到 person2
的地址字段并未受到影响,说明 address
字段已经被深复制。