ByteBuffer.duplicate()创建共享底层数组但指针独立的副本,position/limit/mark互不影响,capacity等只读属性继承,非深拷贝。

ByteBuffer.duplicate() 创建的是一个与原 Buffer 共享底层字节数组、但拥有独立位置(position)、限制(limit)、标记(mark)和容量(capacity)的副本。它不是深拷贝,也不复制数据,只是“视图复刻”。
共享内容:底层数组完全一致
调用 duplicate() 后,新 Buffer 与原 Buffer 使用同一个 byte[] 数组(或同一块直接内存)。任何一方通过 put() 或 get() 修改了数组中的字节,另一方立刻可见。
- 适用于需要多线程分别读写同一段数据,或需保留原始指针状态再另起一路解析的场景
- 注意:如果原 Buffer 是只读的(
asReadOnlyBuffer()得到),duplicate 出来的也是只读的 - 如果原 Buffer 是直接内存(
allocateDirect()),duplicate 后仍指向同一块 native memory
独立指针:position/limit/mark 互不影响
副本初始化时,其 position、limit、mark 均复制自原 Buffer 当前值,但后续各自变更不会同步。
- 比如原 Buffer position=5,duplicate 后两者 position 都是 5;但对副本调用
get()使 position 变成 6,原 Buffer 的 position 仍是 5 -
flip()、rewind()、clear()等操作只影响调用者自身指针状态 - mark 的设置与重置也完全隔离,不会触发对方的
reset()
capacity 和其他属性的继承关系
duplicate 不改变 capacity,副本的 capacity 恒等于原 Buffer 的 capacity;但 remaining()、hasRemaining() 等方法返回值可能不同,因为它们依赖各自的 position 和 limit。
- capacity、isDirect()、isReadOnly()、hasArray() 等只读属性全部继承且不可变
- array() 和 arrayOffset() 在堆内 Buffer 中返回相同引用和偏移,但修改 array() 返回的数组仍会反映在双方 get/put 行为中
- 不能通过 duplicate 改变 Buffer 的“可写性”或“内存类型”,这些由创建方式决定
与其它复制方法的区别
别混淆 duplicate()、slice() 和 asReadOnlyBuffer():
-
slice():共享子区间(从 position 到 limit),capacity 被设为limit - position,且新 position=0 -
asReadOnlyBuffer():共享全部内容,但强制只读;指针仍独立,但 put 类操作抛 ReadOnlyBufferException -
allocate(n)+put(src):才是真正的深拷贝,无任何共享,开销最大

















