网站首页 > java教程 正文
在Java编程中,复制对象是一项常见任务。然而,对象的复制涉及到两个不同的概念:深拷贝(Deep Copy)和浅拷贝(Shallow Copy)。本文将详细介绍深拷贝和浅拷贝的概念、原理和区别,并通过示例代码进行说明,以便更好地理解它们之间的差异。
深拷贝(Deep Copy):
深拷贝是指在复制对象时,不仅复制对象本身,还复制其所有的引用对象。也就是说,通过深拷贝创建的对象与原始对象完全独立,对其中一个对象的修改不会影响到另一个对象。
深拷贝的原理:
在进行深拷贝时,会递归地复制对象及其引用的所有对象。如果对象引用了其他对象,那么深拷贝会创建一个新的对象,并将原对象的引用复制到新对象中。这样,即使原对象和新对象引用相同的对象,它们仍然是独立的。
深拷贝的实现方式:
深拷贝可以通过多种方式实现:
- 通过实现`Cloneable`接口和重写`clone()`方法来实现对象的深拷贝。
- 通过序列化和反序列化对象来实现深拷贝。
示例代码:
下面是一个通过实现`Cloneable`接口和重写`clone()`方法实现深拷贝的示例:
class Person implements Cloneable {
private String name;
private Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = (Address) address.clone();
return cloned;
}
}
class Address implements Cloneable {
private String city;
public Address(String city) {
this.city = city;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class DeepCopyExample {
public static void main(String[] args) {
Address address = new Address("New York");
Person person1 = new Person("John", address);
try {
Person person2 = (Person) person1.clone();
System.out.println(person1 == person2); // false
System.out.println(person1.getAddress() == person2.getAddress()); // false
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
上述示例中,通过重写`clone()`方法,在`Person`类中进行深拷贝。在`clone()`方法中,除了复制`Person`对象本身外,还通过调用`address`对象的`clone()`方法,创建一个新的`Address`对象。
浅拷贝(Shallow Copy):
浅拷贝是指在复制对象时,只复制对象本身,而不复制其引用的对象。也就是说,通过浅拷贝创建的对象与原始对象共享引用对象,对其中一个对象的修改会影响到另一个对象。
浅拷贝的原理:
在进行浅拷贝时,只复制对象本身,而不会递归复制引用的对象。因此,原对象和新对象引用相同的对象,它们之间是共享的。
浅拷贝的实现方式:
浅拷贝可以通过多种方式实现:
- 通过实现`Cloneable`接口和重写`clone()`方法来实现对象的浅拷贝。
- 通过复制构造函数(Copy Constructor)实现浅拷贝。
- 通过对象的工厂方法(Factory Method)实现浅拷贝。
示例代码:
下面是一个通过实现`Cloneable`接口和重写`clone()`方法实现浅拷贝的示例:
class Person implements Cloneable {
private String name;
private Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Address {
private String city;
public Address(String city) {
this.city = city;
}
public void setCity(String city) {
this.city = city;
}
}
public class ShallowCopyExample {
public static void main(String[] args) {
Address address = new Address("New York");
Person person1 = new Person("John", address);
try {
Person person2 = (Person) person1.clone();
System.out.println(person1 == person2); // false
System.out.println(person1.getAddress() == person2.getAddress()); // true
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
上述示例中,通过重写`clone()`方法,在`Person`类中进行浅拷贝。在`clone()`方法中,只调用了`super.clone()`来复制对象本身,而没有对`address`对象进行深层复制。因此,原对象和新对象引用相同的`Address`对象,它们之间是共享的。
深拷贝与浅拷贝的区别:
深拷贝和浅拷贝之间的主要区别如下:
3.1. 复制对象的引用对象:
- 深拷贝:会递归复制对象的引用对象,创建一个新的对象,使得原对象和新对象完全独立。
- 浅拷贝:只复制对象的引用,使得原对象和新对象共享引用对象。
3.2. 对象的修改影响:
- 深拷贝:原对象和新对象之间互不影响,对其中一个对象的修改不会影响到另一个对象。
- 浅拷贝:原对象和新对象之间是共享的,对其中一个对象的修改会影响到另一个对象。
3.3. 性能和效率:
- 深拷贝:由于需要递归复制对象及其引用对象,因此深拷贝可能涉及更多的内存和处理开销,效率较低。
- 浅拷贝:仅复制对象本身,不涉及递归复制,因此浅拷贝的性能较好。
3.4. 对象的可变性:
- 深拷贝:适用于不可变对象和可变对象,可以确保对象的独立性和不可变性。
- 浅拷贝:适用于不可变对象或者希望共享引用对象的可变对象。
结论:
深拷贝和浅拷贝是在Java中实现对象复制的两种方式。深拷贝会递归地复制对象及其引用对象,使得原对象和新对象完全独立,修改一个对象不会影响另一个对象。而浅拷贝只复制对象本身,使得原对象和新对象共享引用对象,修改一个对象会影响另一个对象。选择使用深拷贝还是浅拷贝取决于实际需求和对象的可变性。
- 上一篇: 什么是Java中的引用拷贝、浅拷贝与深拷贝?
- 下一篇: java中浅拷贝和深拷贝的区别 #干货分享
猜你喜欢
- 2024-10-19 Python 中赋值、浅拷贝、深拷贝的区别是什么?
- 2024-10-19 Java 对象拷贝原理剖析(java 对象拷贝原理剖析)
- 2024-10-19 认识Object类和深浅拷贝!(阐述object.assign的用法,深拷贝与浅拷贝的区别?)
- 2024-10-19 三面“有赞”Java岗斩获offer:Spring+JVM+并发锁+分布式+算法
- 2024-10-19 谈谈 Java 开发中的对象拷贝(java对象拷贝工具类)
- 2024-10-19 深入浅出Java中的clone克隆方法,写得也太棒了
- 2024-10-19 深拷贝和浅拷贝之list、dataframe
- 2024-10-19 对象拷贝java 浅谈(java对象的拷贝)
- 2024-10-19 Java克隆对象需要知道的事(java克隆的作用)
- 2024-10-19 Java的Object十二个常用方法,你用过几个?
你 发表评论:
欢迎- 最近发表
-
- 多种负载均衡算法及其Java代码实现
- 输入www.baidu.com背后经历了啥?说清楚这个,已经超过90%的人了
- 优化MySQL:为什么你应该用 UNSIGNED INT 存储IP地址
- 实模式下CPU如何获取数据及指令(实模式寻址方式)
- java基础都在这了,小主们拿去吧(java基础是指什么)
- 盘点爬虫语言为何选择Python而不是Java
- 搭载Dubbo+Zookeeper踩了这么多坑,我终于决定写下这篇
- 网络协议之TCP/IP协议(面试必考内容) - javaEE初阶 - 细节狂魔
- 深夜报警!10亿次请求暴击,如何用Redis找出最热IP?
- VPN技术(IPsec/L2TP/SSLVPN/PPTP)学习笔记
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)