flip()将position值赋给limit并重置position为0,使缓冲区从写入态转为可读态;典型流程为写→flip→读,不调用则读取位置错误或失败。

Java NIO 中的缓冲区(Buffer)本身没有“读取模式”或“写入模式”的显式状态,flip() 的作用是重置指针位置,为后续的读取操作做准备,而不是切换某种抽象模式。它本质上是将缓冲区从“写入后待读”状态调整为“可读取”状态,关键在于 position 和 limit 两个指针的变化。
flip() 做了什么?
调用 flip() 会执行两个操作:
- 把当前
position的值赋给limit(即:limit = position) - 把
position重置为 0
这相当于告诉缓冲区:“我已经写完了数据,现在要从头开始读,最多读到刚才写入的末尾位置。”
典型流程:写 → flip → 读
以 ByteBuffer 为例:
立即学习“Java免费学习笔记(深入)”;
ByteBuffer buf = ByteBuffer.allocate(10); buf.put((byte) 'H').put((byte) 'e').put((byte) 'l').put((byte) 'l').put((byte) 'o'); // 写入 5 字节 // 此时:position = 5, limit = 10, capacity = 10 <p>buf.flip(); // 关键一步 // 此时:position = 0, limit = 5, capacity = 10 → 可安全读前 5 字节</p><p>byte[] data = new byte[buf.remaining()]; // remaining() = limit - position = 5 buf.get(data); // 成功读出 "Hello"</p>
不 flip 会怎样?
如果跳过 flip() 直接调用 get():
-
position仍为 5,get()尝试从索引 5 开始读,但此时limit还是 10,逻辑上“可读范围”是 [5, 10),但实际没写入数据 - 更常见的是读不到有效内容,或者抛
BufferUnderflowException(取决于剩余空间和读取长度) - 即使读成功,拿到的也不是你刚写入的数据
注意 clear() 和 compact() 的区别
别把 flip() 和其它指针操作混淆:
-
clear():重置为“可写状态”(position=0, limit=capacity),适合重复写入新数据 -
compact():把未读完的数据移到开头,position设为已复制长度,limit设为capacity,适合“边读边留部分未读数据继续用” - 只有
flip()是专为“写完立刻读”设计的桥梁操作


















