MST

星途 面试题库

面试题:Java对象克隆中深克隆与浅克隆的实现及应用场景

请详细阐述在Java中深克隆和浅克隆的概念,并且分别给出深克隆和浅克隆的具体实现代码示例,并说明在哪些实际场景下会使用深克隆,哪些场景下会使用浅克隆。
27.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

深克隆和浅克隆概念

  1. 浅克隆
    • 当对象被浅克隆时,克隆对象与原对象共享对其包含的可变对象的引用。也就是说,克隆对象中的成员变量如果是引用类型,这些引用指向的是与原对象相同的实际对象。对克隆对象或原对象中引用类型成员变量的修改,会影响到另一个对象的对应成员变量。
  2. 深克隆
    • 深克隆创建一个完全独立的对象副本,不仅克隆对象本身,还递归地克隆对象内部包含的所有可变对象。这意味着克隆对象和原对象在内存中是完全独立的,对其中一个对象的修改不会影响另一个对象。

浅克隆实现代码示例

class Address {
    private String city;
    public Address(String city) {
        this.city = city;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
}

class Person implements Cloneable {
    private String name;
    private Address address;
    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

测试代码:

public class ShallowCloneTest {
    public static void main(String[] args) {
        try {
            Address address = new Address("Beijing");
            Person person1 = new Person("Alice", address);
            Person person2 = (Person) person1.clone();
            System.out.println("person1 address: " + person1.getAddress().getCity());
            System.out.println("person2 address: " + person2.getAddress().getCity());
            person2.getAddress().setCity("Shanghai");
            System.out.println("person1 address after person2 change: " + person1.getAddress().getCity());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

深克隆实现代码示例

class AddressDeepCloneable implements Cloneable {
    private String city;
    public AddressDeepCloneable(String city) {
        this.city = city;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class PersonDeepCloneable implements Cloneable {
    private String name;
    private AddressDeepCloneable address;
    public PersonDeepCloneable(String name, AddressDeepCloneable address) {
        this.name = name;
        this.address = address;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public AddressDeepCloneable getAddress() {
        return address;
    }
    public void setAddress(AddressDeepCloneable address) {
        this.address = address;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        PersonDeepCloneable cloned = (PersonDeepCloneable) super.clone();
        cloned.address = (AddressDeepCloneable) address.clone();
        return cloned;
    }
}

测试代码:

public class DeepCopyTest {
    public static void main(String[] args) {
        try {
            AddressDeepCloneable address = new AddressDeepCloneable("Beijing");
            PersonDeepCloneable person1 = new PersonDeepCloneable("Alice", address);
            PersonDeepCloneable person2 = (PersonDeepCloneable) person1.clone();
            System.out.println("person1 address: " + person1.getAddress().getCity());
            System.out.println("person2 address: " + person2.getAddress().getCity());
            person2.getAddress().setCity("Shanghai");
            System.out.println("person1 address after person2 change: " + person1.getAddress().getCity());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

实际使用场景

  1. 浅克隆场景
    • 性能优先且对象内部可变对象不会被修改:如果对象包含的引用类型成员变量在整个生命周期内不会被修改,并且对克隆操作的性能有较高要求,可以使用浅克隆。例如,一个包含只读配置信息的对象,这些配置信息在程序运行过程中不会改变,浅克隆可以节省内存和时间开销。
  2. 深克隆场景
    • 对象独立性要求高:当需要确保克隆对象和原对象完全独立,对其中一个对象的任何修改都不能影响另一个对象时,使用深克隆。比如在游戏开发中,克隆一个游戏角色对象,每个角色的属性(如装备、技能等,这些可能是复杂的对象)需要独立存在,不能因为克隆对象的属性改变而影响原对象,此时就需要深克隆。