网站首页 > 精选教程 正文
在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中实现对象复制的两种方式。深拷贝会递归地复制对象及其引用对象,使得原对象和新对象完全独立,修改一个对象不会影响另一个对象。而浅拷贝只复制对象本身,使得原对象和新对象共享引用对象,修改一个对象会影响另一个对象。选择使用深拷贝还是浅拷贝取决于实际需求和对象的可变性。
猜你喜欢
- 2024-11-30 Java中的四种引用详解
- 2024-11-30 你不知道的java对象序列化的秘密
- 2024-11-30 「面试专题」2020最新java面试3(反射、对象拷贝、javaweb)
- 2024-11-30 从源码入手,手把手带你剖析Java类加载的双亲委派
- 2024-11-30 万字长文:细谈Linux、JDK、Netty中NIO与零拷贝
- 2024-11-30 java数组的拷贝及Arrays类
- 2024-11-30 Java 创建对象的四种方法
- 2024-11-30 RocketMQ源码分析之主从数据复制
- 2024-11-30 Java对象栈上分配
- 2024-11-30 java深入理解浅拷贝和深拷贝
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)