本篇文章提供了Java编程语言中实现对象深拷贝和浅拷贝的具体示例代码,并分析了两者的区别及应用场景。通过阅读本文,读者可以更好地理解如何在实际开发过程中运用这两种技术。
Java中的深拷贝(深度复制)与浅拷贝(浅层复制)是两种不同的对象克隆方式。
浅拷贝是指创建一个新对象,并将原对象中所有可访问的成员变量值复制到新的实例中,但这些成员变量所引用的对象不会被复制。因此,在进行浅拷贝后,源对象和目标对象会共享相同的引用地址(即内存位置)来指向那些不可变或复杂的数据结构。
而深拷贝则是创建一个全新的独立对象,并且递归地将原对象中的所有可访问字段也完全克隆一份出来,而不是仅仅是复制它们的引用。这意味着,在执行完深拷贝操作之后,源和目标两个实例之间不再有任何共享状态或者相互依赖关系了。
下面通过示例代码来展示浅拷贝与深拷贝的区别:
```java
import java.util.ArrayList;
import java.io.Serializable;
class User implements Cloneable, Serializable {
private String name;
public ArrayList hobbies = new ArrayList<>();
// 构造函数、getter和setter省略
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class DeepCopyVsShallowCopyDemo {
public static void main(String[] args) throws Exception {
User user1 = new User(张三);
// 浅拷贝示例:
User shallowUser2 = (User) user1.clone();
System.out.println(user1.hobbies == shallowUser2.hobbies); // 输出:true
// 深拷贝示例(使用序列化实现):
byte[] bytes = serializeObject(user1);
User deepCopyOfUser1 = deserializeBytes(bytes);
System.out.println(user1.hobbies == deepCopyOfUser1.hobbies); // 输出:false
}
private static byte[] serializeObject(Object obj) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
return bos.toByteArray();
}
private static Object deserializeBytes(byte[] bytes) throws Exception {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
```
在这个例子中,我们首先创建了一个名为`User`的类,并且该类实现了`Cloneable`接口以便能够执行浅拷贝。然后我们在主函数里分别演示了如何通过直接调用克隆方法来实现浅层复制以及怎样借助Java序列化机制完成深度复制的过程。最后输出的结果表明,对于复杂类型字段(这里使用的是ArrayList),深拷贝后的新对象与原始对象之间不再共享引用地址;而进行浅拷贝操作后的两个实例仍然共用了同一个`hobbies`列表的内存位置。
希望这个解释和示例代码能够帮助理解Java中关于深拷贝和浅拷贝的概念。