Java 深拷贝时集合对象未拷贝
引言
在Java编程中,我们经常需要对对象进行拷贝操作。拷贝操作可以分为浅拷贝和深拷贝两种。浅拷贝只复制对象的引用,而深拷贝则是创建一个全新的对象,将原对象的所有属性复制到新对象中。然而,在进行深拷贝时,我们可能会遇到集合对象未被正确拷贝的问题。本文将介绍这个问题的原因以及如何解决。
问题描述
当我们进行深拷贝操作时,使用的是对象的clone()
方法或者序列化方式。在大多数情况下,这些方法可以正确地拷贝对象的属性。然而,当对象中包含集合对象时,拷贝的结果可能会出现问题。
import java.util.ArrayList;
import java.util.List;
public class Person implements Cloneable {
private String name;
private List<String> hobbies;
public Person(String name, List<String> hobbies) {
this.name = name;
this.hobbies = hobbies;
}
public String getName() {
return name;
}
public List<String> getHobbies() {
return hobbies;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
List<String> hobbies = new ArrayList<>();
hobbies.add("reading");
hobbies.add("swimming");
Person person1 = new Person("Alice", hobbies);
Person person2 = (Person) person1.clone();
// 修改person2的hobbies
person2.getHobbies().add("dancing");
System.out.println(person1.getHobbies()); // [reading, swimming, dancing]
System.out.println(person2.getHobbies()); // [reading, swimming, dancing]
}
}
上述代码中,我们创建了一个Person
类,包含了一个hobbies
属性,它是一个List
集合。在main
方法中,我们创建了一个person1
对象,并将其hobbies
属性设置为[reading, swimming]
。然后,我们使用clone()
方法创建了一个person2
对象。
接着,我们修改了person2
对象的hobbies
属性,向其中添加了一个新的元素dancing
。然而,我们发现person1
的hobbies
属性也被修改了,结果变成了[reading, swimming, dancing]
。这不是我们所期望的拷贝结果。
深拷贝中集合对象未被拷贝的原因
上述问题的原因在于,集合对象的拷贝仅仅是拷贝了它的引用,而没有创建一个新的集合对象。因此,当我们修改其中一个集合对象时,另一个集合对象也会被修改。
在上述代码中,person2
的hobbies
属性实际上引用了和person1
相同的ArrayList
对象。因此,当我们向person2
的hobbies
中添加元素时,实际上是修改了ArrayList
对象本身,而不是创建一个新的对象。
解决方案
要解决上述问题,我们需要在深拷贝过程中,对集合对象也进行拷贝操作。下面是一种解决方案:
import java.util.ArrayList;
import java.util.List;
public class Person implements Cloneable {
private String name;
private List<String> hobbies;
public Person(String name, List<String> hobbies) {
this.name = name;
this.hobbies = new ArrayList<>(hobbies);
}
public String getName() {
return name;
}
public List<String> getHobbies() {
return new ArrayList<>(hobbies);
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person clone = (Person) super.clone();
clone.hobbies = new ArrayList<>(this.hobbies);
return clone;
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
List<String> hobbies = new ArrayList<>();
hobbies.add("reading");
hobbies.add("swimming");
Person person1 = new Person("Alice", hobbies);
Person person2 = (Person) person1.clone();
// 修改person2的hobbies
person2.getHobbies().add("dancing");
System.out.println(person1.get