📜  通过示例了解Java中的对象克隆(1)

📅  最后修改于: 2023-12-03 14:58:07.374000             🧑  作者: Mango

通过示例了解Java中的对象克隆

在Java中,对象克隆是指创建一个与原始对象具有相同状态的新对象的过程。这个过程可以通过实现Cloneable接口和重写Object类的clone()方法来实现。

实现Cloneable接口

当一个类实现了Cloneable接口时,它表示该类可以被克隆。这是一个标记接口,没有任何方法需要实现。

以下是一个示例:

public class Person implements Cloneable {
    private String name;
    private int age;

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

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

    // getter and setter methods
}

在这里,Person类实现了Cloneable接口,并重写了Object类的clone()方法。由于Object的clone()方法返回的是Object类型,因此需要将其强制转换为Person类型。

浅克隆和深克隆

在Java中,有两种克隆方式:浅克隆和深克隆。

浅克隆

浅克隆是指只复制对象本身,而不复制它所引用的对象。也就是说,如果原始对象中有引用类型的成员变量,那么它们在克隆后会引用同一个对象。

以下是一个示例:

public class Address {
    private String street;
    private String city;

    public Address(String street, String city) {
        this.street = street;
        this.city = city;
    }

    // getter and setter methods
}

public 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
    public Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }

    // getter and setter methods
}

Address address = new Address("123 Main St", "Anytown");
Person person1 = new Person("John", 30, address);
Person person2 = person1.clone();

person2.setName("Bob");
person2.getAddress().setStreet("456 Oak St");

System.out.println(person1); // Person{name='John', age=30, address=Address@15db9742}
System.out.println(person2); // Person{name='Bob', age=30, address=Address@15db9742}

在这里,我们创建了一个Person对象person1,并将它克隆到person2。在修改person2的地址时,person1的地址也被修改了,因为它们引用的是同一个Address对象。

深克隆

深克隆是指复制对象本身以及它所引用的所有对象。也就是说,如果原始对象中有引用类型的成员变量,那么它们在克隆后会引用不同的对象。

以下是一个示例:

public class Address {
    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();
    }

    // getter and setter methods
}

public 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
    public Person clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        cloned.address = this.address.clone();
        return cloned;
    }

    // getter and setter methods
}

Address address = new Address("123 Main St", "Anytown");
Person person1 = new Person("John", 30, address);
Person person2 = person1.clone();

person2.setName("Bob");
person2.getAddress().setStreet("456 Oak St");

System.out.println(person1); // Person{name='John', age=30, address=Address@15db9742}
System.out.println(person2); // Person{name='Bob', age=30, address=Address@6d06d69c}

在这里,我们创建了一个Person对象person1,并将它克隆到person2。在修改person2的地址时,person1的地址没有被修改,因为它们引用的是不同的Address对象。

总结

通过实现Cloneable接口和重写Object类的clone()方法,可以在Java中实现对象克隆。在克隆对象时,可以选择浅克隆或深克隆,以便复制对象本身以及它所引用的所有对象。