MST

星途 面试题库

面试题:Java中浅拷贝的实现方式及局限性

请简述在Java中如何实现对象的浅拷贝,并且说明浅拷贝在什么场景下会出现数据不一致的问题。假设存在一个包含基本数据类型和引用数据类型的类,给出实现浅拷贝的代码示例。
48.2万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

浅拷贝的实现方式

在Java中,实现对象的浅拷贝可以通过实现 Cloneable 接口并重写 clone() 方法来实现。Cloneable 接口是一个标记接口,它本身不包含任何方法,只是表明该类支持克隆操作。

浅拷贝出现数据不一致的场景

浅拷贝只是复制对象的基本数据类型字段,对于引用数据类型字段,只是复制了引用,而不是引用指向的对象。这就导致当原对象和拷贝对象中的引用数据类型字段指向同一个对象时,如果其中一个对象通过引用修改了该对象的状态,另一个对象也会受到影响,从而出现数据不一致的问题。

代码示例

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 int age;
    private String name;
    private Address address;

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

    public int getAge() {
        return age;
    }

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

    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 Main {
    public static void main(String[] args) {
        Address address = new Address("Beijing");
        Person person1 = new Person(30, "Alice", address);
        try {
            Person person2 = (Person) person1.clone();
            System.out.println("person1 address: " + person1.getAddress().getCity());
            System.out.println("person2 address: " + person2.getAddress().getCity());

            // 修改person2的地址
            person2.getAddress().setCity("Shanghai");
            System.out.println("After modification:");
            System.out.println("person1 address: " + person1.getAddress().getCity());
            System.out.println("person2 address: " + person2.getAddress().getCity());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,Person 类包含基本数据类型 agename 以及引用数据类型 AddressPerson 类实现了 Cloneable 接口并重写了 clone() 方法。在 main 方法中,创建了 person1 对象并克隆出 person2 对象,然后修改 person2Address 中的 city,可以看到 person1Address 中的 city 也发生了变化,这就是浅拷贝导致数据不一致的情况。