淘先锋技术网

首页 1 2 3 4 5 6 7

在Java中,对象的拷贝分为浅拷贝和深拷贝两种。浅拷贝只复制对象的引用,而深拷贝是创建一个新的对象并复制其中的所有属性值。

java哪些是深拷贝和浅拷贝

以下是Java中常见的浅拷贝和深拷贝的情况:


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

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

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

Person p1 = new Person("Tom", 20);

// 浅拷贝
Person p2 = p1;
p2.setName("Jerry");
System.out.println(p1.getName()); // "Jerry"

// 深拷贝
Person p3 = (Person) p1.clone();
p3.setName("Kate");
System.out.println(p1.getName()); // "Jerry"
System.out.println(p3.getName()); // "Kate"

从上述代码中可以看出,当我们对p2进行修改时,p1的值也被改变了,这是因为p2只是p1的引用,它们指向同一个对象。而当我们对p3进行修改时,p1的值没有被改变,这是因为p3是一个新的对象,它与p1没有任何关系。

对于基本数据类型和不可变对象,比如String,浅拷贝和深拷贝没有任何区别。但对于可变对象,如数组和集合,需要格外小心,因为它们中的元素可能也是引用类型。在进行深拷贝时,我们需要递归地拷贝其中的元素。


public class MyClass implements Cloneable {
    private String[] arr;
  
    public MyClass(String[] arr) {
        this.arr = arr;
    }
  
    public Object clone() throws CloneNotSupportedException {
        MyClass copy = (MyClass) super.clone();
        copy.arr = this.arr.clone();
        return copy;
    }
}

String[] arr1 = { "a", "b", "c" };
MyClass obj1 = new MyClass(arr1);

// 浅拷贝
MyClass obj2 = obj1;
obj2.getArr()[1] = "d";
System.out.println(obj1.getArr()[1]); // "d"

// 深拷贝
MyClass obj3 = (MyClass) obj1.clone();
obj3.getArr()[1] = "e";
System.out.println(obj1.getArr()[1]); // "d"
System.out.println(obj3.getArr()[1]); // "e"

在进行深拷贝时,我们需要确保所有的对象都实现了Cloneable接口并正确地重写了clone方法。同时,我们也可以使用第三方库来简化深拷贝的过程,比如Apache Commons Lang库中的SerializationUtils.deepClone方法。