在Java中,对象的拷贝分为浅拷贝(Shallow Copy)和深拷贝(Deep Copy)两种,它们的区别主要在于如何处理对象中的引用类型成员变量。
浅拷贝(Shallow Copy)
浅拷贝创建一个新的对象,然后将当前对象的非静态字段复制到新对象。如果字段是值类型的,那么直接进行值拷贝;如果字段是引用类型,那么只复制引用,而不复制引用指向的对象。这意味着新旧对象的引用类型字段指向同一个对象。
浅拷贝的实现通常可以通过实现 Cloneable
接口并重写 clone()
方法来完成。例如:
public class ShallowCopyExample implements Cloneable {
public int x;
public int[] array;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
在这个例子中,如果创建了一个 ShallowCopyExample
对象并对其进行浅拷贝,那么新对象的 array
字段将与原对象共享同一个数组实例。
深拷贝(Deep Copy)
深拷贝也创建一个新的对象,并且递归地将当前对象的非静态字段复制到新对象。对于值类型字段,同样进行值拷贝;对于引用类型字段,会创建一个新的对象,并将原对象中引用类型字段的内容复制到新对象中。这意味着新旧对象的引用类型字段指向不同的对象。
深拷贝的实现通常需要手动复制引用类型的字段,或者通过序列化和反序列化的方式来实现。例如:
public class DeepCopyExample implements Cloneable {
public int x;
public int[] array;
@Override
protected Object clone() throws CloneNotSupportedException {
DeepCopyExample clone = (DeepCopyExample) super.clone();
clone.array = clone.array.clone(); // 对引用类型字段进行深拷贝
return clone;
}
}
在这个例子中,如果创建了一个 DeepCopyExample
对象并对其进行深拷贝,那么新对象的 array
字段将是一个新的数组实例,其内容与原对象的数组相同,但两个数组实例是独立的。
总结
- 浅拷贝:复制对象时,对于引用类型字段,只复制引用,不复制引用的对象。
- 深拷贝:复制对象时,对于引用类型字段,不仅复制引用,还复制引用的对象。
在选择浅拷贝还是深拷贝时,需要根据实际需求来决定。如果对象的引用类型字段不需要独立于原对象,可以使用浅拷贝;如果需要完全独立的对象副本,则应使用深拷贝。