Java对象深浅拷贝详解与实例
81 浏览量
更新于2024-09-01
收藏 100KB PDF 举报
"这篇文档详细解释了Java中的对象拷贝,包括浅拷贝和深拷贝的概念,并通过实例展示了如何实现。"
在Java编程中,对象拷贝是一个关键概念,尤其是当你需要创建一个对象的独立副本,使得原对象和副本在后续修改时互不影响。Java的赋值操作实际上是复制对象的引用,而不是对象本身,这意味着两个引用指向同一个内存位置。例如,当我们执行`Person p2 = p1;`时,`p1`和`p2`都指向了同一个Person对象。
要实现真正的对象复制,我们需要使用克隆(clone)机制。Java的`Object`类提供了一个`clone()`方法,但是它是受保护的(`protected`),默认情况下不对外部类公开。因此,如果我们想要在自定义类中使用`clone()`,需要遵循以下步骤:
1. 实现`Cloneable`接口:这是一个标记接口,不包含任何方法。实现这个接口告诉Java你的类支持克隆。
2. 覆盖`clone()`方法:将它的访问修饰符改为`public`,以便在类的外部调用。通常,你只需调用`super.clone()`来执行默认的克隆行为。
以下是一个简单的示例,展示了一个名为`Person`的类如何实现克隆:
```java
@Data
public class Person implements Cloneable {
private String name;
private Integer age;
private Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
```
在这个例子中,`Person`类包含了两个基本类型(`String`和`Integer`)和一个引用类型(`Address`)。当执行`p1.clone()`时,如果`Address`对象也实现了`Cloneable`并覆盖了`clone()`方法,那么`Address`对象也会被深拷贝。然而,如果没有这样做,`Address`对象将只进行浅拷贝,意味着`p1`和`p2`的`address`字段仍然指向同一个`Address`实例。
通过以下测试用例,我们可以看到深拷贝的效果:
```java
@Test
public void testShallowCopy() throws Exception {
Person p1 = new Person();
p1.setAge(31);
p1.setName("Peter");
Person p2 = (Person) p1.clone();
System.out.println(p1 == p2); // false,表明p1和p2是不同的对象
p2.setName("Jacky");
System.out.println("p1=" + p1); // p1=Person[name=Peter,age=31]
System.out.println("p2=" + p2); // p2=Person[name=Jacky,age=31]
}
```
在这个测试中,`p1`和`p2`的`name`属性被独立修改,证明了它们是相互独立的对象副本。然而,如果`Address`对象也包含可变属性,而没有被深拷贝,那么修改`p2`的`address`属性会影响到`p1`的`address`属性,这就是浅拷贝的特性。
总结来说,Java对象拷贝分为浅拷贝和深拷贝。浅拷贝只复制对象本身,而不复制其引用的对象;深拷贝则会递归地复制对象及其所有嵌套的对象。在实现克隆时,确保所有可变的嵌套对象都支持深拷贝,才能确保对象副本的真正独立。
2020-08-26 上传
2020-08-26 上传
2020-09-01 上传
2020-08-30 上传
2020-08-31 上传
2020-08-31 上传
2020-08-31 上传
2022-01-13 上传
2020-08-31 上传
weixin_38734269
- 粉丝: 3
- 资源: 930
最新资源
- 正整数数组验证库:确保值符合正整数规则
- 系统移植工具集:镜像、工具链及其他必备软件包
- 掌握JavaScript加密技术:客户端加密核心要点
- AWS环境下Java应用的构建与优化指南
- Grav插件动态调整上传图像大小提高性能
- InversifyJS示例应用:演示OOP与依赖注入
- Laravel与Workerman构建PHP WebSocket即时通讯解决方案
- 前端开发利器:SPRjs快速粘合JavaScript文件脚本
- Windows平台RNNoise演示及编译方法说明
- GitHub Action实现站点自动化部署到网格环境
- Delphi实现磁盘容量检测与柱状图展示
- 亲测可用的简易微信抽奖小程序源码分享
- 如何利用JD抢单助手提升秒杀成功率
- 快速部署WordPress:使用Docker和generator-docker-wordpress
- 探索多功能计算器:日志记录与数据转换能力
- WearableSensing: 使用Java连接Zephyr Bioharness数据到服务器