Effective Java笔记(13)谨慎地覆盖 clone
发布人:shili8
发布时间:2025-01-03 14:35
阅读次数:0
**谨慎地覆盖clone**
在Java中,`clone()`方法是Object类的一个方法,它允许对象创建一个新的、浅拷贝的副本。然而,在实际应用中,使用`clone()`方法可能会带来一些问题。
###1. clone()方法的缺陷首先,我们需要了解`clone()`方法的缺陷。`clone()`方法是Object类的一个方法,它返回该对象的一个副本。如果我们覆盖了这个方法,那么它应该返回一个新的、浅拷贝的副本。但是,如果我们没有正确地覆盖这个方法,可能会导致一些问题。
例如,我们有一个Person类:
javapublic class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
在这个例子中,我们覆盖了`clone()`方法,但是我们没有正确地实现它。我们只是返回了一个新的Person对象,而不是一个浅拷贝的副本。
###2. 浅拷贝和深拷贝接下来,我们需要了解浅拷贝和深拷贝的区别。浅拷贝是指创建一个新对象,并将原对象中的所有字段复制到新对象中。但是,如果原对象中的某个字段是引用类型(如数组或集合),那么浅拷贝会导致两个对象共享同一个引用。
例如,我们有一个Person类:
javapublic class Person {
private String name;
private int[] scores;
public Person(String name, int[] scores) {
this.name = name;
this.scores = scores;
}
}
如果我们使用浅拷贝来创建一个新的Person对象,那么两个对象会共享同一个int[]scores引用:
javapublic class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person("John", new int[]{90,80,70});
Person person2 = (Person) person1.clone();
// 修改person1的scores person1.scores[0] =100;
System.out.println(person1.scores[0]); // 输出:100 System.out.println(person2.scores[0]); // 输出:100 }
}
如上所示,浅拷贝导致两个对象共享同一个引用。
深拷贝是指创建一个新对象,并将原对象中的所有字段复制到新对象中,同时也复制了原对象中的所有子对象。
例如,我们有一个Person类:
javapublic class Person {
private String name;
private int[] scores;
public Person(String name, int[] scores) {
this.name = name;
this.scores = scores.clone(); // 使用clone()方法复制scores }
}
在这个例子中,我们使用了clone()方法来复制scores数组。这样,两个Person对象就不会共享同一个引用。
###3. 覆盖clone()
现在我们知道了浅拷贝和深拷贝的区别,我们可以覆盖clone()方法来实现深拷贝。
例如,我们有一个Person类:
javapublic class Person implements Cloneable {
private String name;
private int[] scores;
public Person(String name, int[] scores) {
this.name = name;
this.scores = scores.clone(); // 使用clone()方法复制scores }
@Override protected Object clone() throws CloneNotSupportedException {
Person person = (Person) super.clone();
person.scores = scores.clone(); // 复制scores return person;
}
}
在这个例子中,我们覆盖了clone()方法,并且复制了scores数组。这样,两个Person对象就不会共享同一个引用。
###4. 总结在本文中,我们讨论了Java中的clone()方法及其缺陷。我们了解了浅拷贝和深拷贝的区别,并覆盖了clone()方法来实现深拷贝。通过这种方式,我们可以确保对象之间不会共享同一个引用,从而避免一些潜在的问题。
**参考**
* Effective Java(中文版)- Item10:谨慎地覆盖 clone* Java API 文档:Object.clone()
* Java API 文档:Cloneable

