duplicate() 创建共享底层数组的独立视图,position/limit/mark 互不影响,但写入会同步到原缓冲区;适用于多线程处理同一数据、保留原始位置或生成多逻辑通道,非深拷贝。

duplicate() 不是复制数据,而是创建共享底层数组的新视图。它返回一个与原缓冲区拥有相同内容、位置、限制和标记的副本,但两个缓冲区的指针(position、limit、mark)相互独立,且修改彼此的指针不会影响对方;而底层数据(如 backing array)仍共用同一份内存。
duplicate 的核心特性
调用 buffer.duplicate() 后得到的新缓冲区:
- 共享相同的底层数据(例如 byte[] 数组),所有写入操作会反映在原缓冲区上(如果是可写的堆缓冲区)
- 拥有独立的 position、limit、mark —— 移动新缓冲区的位置不会改变原缓冲区的位置
- capacity 和 remaining() 初始值与原缓冲区一致
- 只适用于直接缓冲区或堆缓冲区,对只读缓冲区 duplicate 后仍是只读的
典型使用场景
常见于需要「多路并发处理同一段数据」但又不想重复拷贝时:
- 将一个 ByteBuffer 拆成多个子视图,分别交给不同线程解析协议字段(如 header + body)
- 在编码前保留原始 position,以便后续回溯或重试
- 为同一个数据生成多个逻辑通道(比如同时做校验和序列化)
注意与其它复制方法的区别
别混淆 duplicate 和以下方法:
-
slice():创建从当前 position 开始到 limit 的子视图,capacity = limit - position,position = 0 -
asReadOnlyBuffer():返回只读副本,底层仍共享,但无法写入 -
allocate(n)+put(...):真正复制数据到新缓冲区(深拷贝),内存开销大
简单示例
假设有一个初始缓冲区:
ByteBuffer bb = ByteBuffer.allocate(10); bb.put((byte)1).put((byte)2).put((byte)3); // position=3, limit=10 ByteBuffer dup = bb.duplicate();
此时:
- bb.position()==3,dup.position()==3,但
dup.position(0)不会影响 bb - bb.array() == dup.array() → 引用同一数组
- 若执行
dup.put((byte)99),则 bb.array()[3] 也会变成 99
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











