浅拷贝(Shallow Copy)在 Java 中
-
定义:浅拷贝创建一个新对象,但不复制对象中引用的其他对象。这意味着新对象和原对象中的引用将指向相同的对象。
-
实现:在 Java 中,浅拷贝通常通过实现
Cloneable
接口并重写clone()
方法来完成。Object
类提供的clone()
方法默认实现是浅拷贝。
import java.util.Arrays;
public class ShallowCopyExample implements Cloneable {
private int[] array;
public ShallowCopyExample(int[] array) {
this.array = array;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return Arrays.toString(array);
}
public static void main(String[] args) {
int[] originalArray = {1, 2, 3};
ShallowCopyExample original = new ShallowCopyExample(originalArray);
try {
ShallowCopyExample copy = (ShallowCopyExample) original.clone();
System.out.println("Original: " + original);
System.out.println("Copy: " + copy);
// 修改原对象中的数组
originalArray[0] = 99;
System.out.println("After modifying original array:");
System.out.println("Original: " + original);
System.out.println("Copy: " + copy);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
打印结果:
Original: [1, 2, 3]
Copy: [1, 2, 3]
After modifying original array:
Original: [99, 2, 3]
Copy: [99, 2, 3]
由此可以看出浅拷贝,对象中的对象只是拷贝的引用地址,数组值变了,对象中数组的值也变了.
深拷贝(Deep Copy)在 Java 中
-
定义:深拷贝创建一个新对象,并递归地复制对象中所有引用的其他对象。这意味着新对象和原对象完全独立,没有共享引用。
-
实现:深拷贝通常需要显式地复制所有嵌套的对象。你可以在
clone()
方法中实现深拷贝逻辑,或者通过其他手段(如序列化)实现。
import java.util.Arrays;
public class DeepCopyExample implements Cloneable {
private int[] array;
public DeepCopyExample(int[] array) {
this.array = array.clone(); // 使用 clone() 方法创建数组的深拷贝
}
@Override
protected Object clone() throws CloneNotSupportedException {
DeepCopyExample copy = (DeepCopyExample) super.clone();
copy.array = this.array.clone(); // 确保数组被深拷贝
return copy;
}
@Override
public String toString() {
return Arrays.toString(array);
}
public static void main(String[] args) {
int[] originalArray = {1, 2, 3};
DeepCopyExample original = new DeepCopyExample(originalArray);
try {
DeepCopyExample copy = (DeepCopyExample) original.clone();
System.out.println("Original: " + original);
System.out.println("Copy: " + copy);
// 修改原对象中的数组
originalArray[0] = 99;
System.out.println("After modifying original array:");
System.out.println("Original: " + original);
System.out.println("Copy: " + copy);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
打印输出结果:
Original: [1, 2, 3]
Copy: [1, 2, 3]
After modifying original array:
Original: [99, 2, 3]
Copy: [1, 2, 3]
- 初始时,
original
和copy
的数组内容相同。 - 修改
originalArray
中的值(将第一个元素设置为 99),只会影响original
中的数组内容,而copy
中的数组内容保持不变,因为它们的数组数据是完全独立的。
总结
- 浅拷贝:新对象和原对象共享相同的内部对象,修改内部对象会影响到所有引用了该对象的地方。
- 深拷贝:新对象和原对象完全独立,修改新对象中的数据不会影响原对象。
零拷贝
零拷贝(Zero-Copy)是一种优化技术,用于减少数据在计算机系统中移动的次数,从而提高数据处理的效率。在传统的数据传输过程中,数据往往需要在多个缓冲区之间复制,这样不仅耗费了时间,还增加了 CPU 的负担。零拷贝技术的目标是减少这些不必要的数据复制操作。
在网络编程中,零拷贝通常用于优化文件读取和网络传输过程。具体来说,零拷贝技术可以通过以下几种方式实现:
-
直接 I/O(Direct I/O):通过绕过系统缓冲区,直接将数据从磁盘读取到用户空间的缓冲区,减少数据复制的次数。
-
内存映射(Memory Mapping):使用
mmap
函数将文件映射到进程的地址空间中,这样进程可以直接访问文件内容,而不需要进行额外的数据复制。 -
sendfile
系统调用:在 Linux 和一些其他操作系统中,sendfile
系统调用可以直接将文件的数据从文件描述符发送到网络套接字,而无需将数据先复制到用户空间。 -
splice
系统调用:类似于sendfile
,splice
可以在内核空间内直接将数据从一个文件描述符传输到另一个文件描述符,避免了用户空间的干预。
通过这些技术,零拷贝能够显著提高系统的性能,尤其是在处理大量数据传输时。