Java对象深浅拷贝详解与实例
140 浏览量
更新于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 上传
2023-04-19 上传
2023-07-28 上传
2023-05-14 上传
2023-09-02 上传
2023-09-12 上传
2023-09-14 上传
2023-03-31 上传
weixin_38734269
- 粉丝: 3
- 资源: 930
最新资源
- OptiX传输试题与SDH基础知识
- C++Builder函数详解与应用
- Linux shell (bash) 文件与字符串比较运算符详解
- Adam Gawne-Cain解读英文版WKT格式与常见投影标准
- dos命令详解:基础操作与网络测试必备
- Windows 蓝屏代码解析与处理指南
- PSoC CY8C24533在电动自行车控制器设计中的应用
- PHP整合FCKeditor网页编辑器教程
- Java Swing计算器源码示例:初学者入门教程
- Eclipse平台上的可视化开发:使用VEP与SWT
- 软件工程CASE工具实践指南
- AIX LVM详解:网络存储架构与管理
- 递归算法解析:文件系统、XML与树图
- 使用Struts2与MySQL构建Web登录验证教程
- PHP5 CLI模式:用PHP编写Shell脚本教程
- MyBatis与Spring完美整合:1.0.0-RC3详解