📜  Java中的属性 clone() 方法及示例(1)

📅  最后修改于: 2023-12-03 15:02:01.968000             🧑  作者: Mango

Java中的属性 clone() 方法及示例

在Java中,可以使用clone()方法对对象进行浅拷贝或深拷贝。在属性较多并且创建对象较为耗时时,我们可以使用clone()方法对现有的对象进行复制操作,以达到节省时间和提高效率的目的。在这篇文章中,我们就来介绍一下Java中的属性clone()方法及其示例。

什么是clone()方法

clone()方法是一个本地方法,被用来创建当前对象的副本。这个方法在Object类中声明为:

protected native Object clone() throws CloneNotSupportedException;

从这里我们可以看出,clone()方法返回的是一个Object类型的副本对象,需要注意的是,如果要使用clone()方法复制一个对象,该对象的类必须实现Cloneable接口。如果没有实现该接口,会抛出一个CloneNotSupportedException异常。

如何使用clone()方法

为了使用clone()方法,我们需要注意以下两点:

  • 类必须实现Cloneable接口
  • 在类中,必须覆盖clone()方法并将访问修饰符改为public
public class Person implements Cloneable {
    private String name;
    private int age;

    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    public String getName(){
        return name;
    }

    public int getAge(){
        return age;
    }

    public void setName(String name){
        this.name = name;
    }

    public void setAge(int age){
        this.age = age;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

如上代码所示,我们在Person类中实现了Cloneable接口,并对clone()方法进行了覆盖,将访问修饰符改为了public。

如何进行深拷贝

在默认情况下,使用clone()方法进行拷贝时,是浅拷贝。即如果当前对象中有引用类型的属性,那么拷贝出来的对象和当前对象将引用同一个对象。这时候,如果我们要进行深拷贝,那么我们就需要在覆盖clone()方法时,通过创建新对象并将引用类型的属性也进行复制的方式,才能实现深拷贝。

public class Person implements Cloneable {
    private String name;
    private int age;
    private List<String> hobbies;

    public Person(String name, int age, List<String> hobbies){
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
    }

    public String getName(){
        return name;
    }

    public int getAge(){
        return age;
    }

    public void setName(String name){
        this.name = name;
    }

    public void setAge(int age){
        this.age = age;
    }

    public List<String> getHobbies(){
        return hobbies;
    }

    public void setHobbies(List<String> hobbies){
        this.hobbies = hobbies;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Person clonePerson = (Person) super.clone();
        clonePerson.hobbies = new ArrayList<>(this.hobbies);
        return clonePerson;
    }
}

如上代码所示,我们在Person类中新增了一个List类型的属性hobbies,并在重写clone()方法中,手动创建一个新的ArrayList对象,并将当前对象的hobbies属性复制到该新对象中,从而实现了深拷贝。

示例
public static void main(String[] args) throws CloneNotSupportedException {
    Person person1 = new Person("zhangsan", 20, new ArrayList<>(Arrays.asList("swimming", "music")));

    System.out.println("原始对象:" + person1.getName() + "," + person1.getAge() + "," + person1.getHobbies());

    Person person2 = (Person) person1.clone();
    System.out.println("克隆对象:" + person2.getName() + "," + person2.getAge() + "," + person2.getHobbies());

    person2.setName("lisi");
    person2.getHobbies().add("reading");

    System.out.println("修改后的克隆对象:" + person2.getName() + "," + person2.getAge() + "," + person2.getHobbies());
    System.out.println("未修改的原始对象:" + person1.getName() + "," + person1.getAge() + "," + person1.getHobbies());
}

如上代码所示,我们在main方法中创建了一个Person对象,并调用clone()方法进行拷贝。之后,我们修改了拷贝出来的对象,并输出原始对象和克隆对象的信息,以及修改后的克隆对象和未修改的原始对象的信息。代码输出如下:

原始对象:zhangsan,20,[swimming, music]
克隆对象:zhangsan,20,[swimming, music]
修改后的克隆对象:lisi,20,[swimming, music, reading]
未修改的原始对象:zhangsan,20,[swimming, music]

从结果可以看出,拷贝出来的对象和原始对象的属性值相同,但是在对拷贝出来的对象进行修改后,原始对象的属性值并没有发生变化,从而验证了clone()方法的正确性。

总结

在Java中,使用clone()方法可以方便地对对象进行复制操作,实现拷贝的效果。但需要注意的是,浅拷贝和深拷贝的区别,在复制引用类型的属性时,需要手动创建新的对象并复制到该新对象中才能实现深拷贝。