flip()是ByteBuffer从写模式切换到读模式的精准指针重置操作:将limit设为当前position值、position重置为0,不改变capacity、底层数组和mark(mark被清为-1),确保后续get()从头读取已写入的有效数据。

flip 做了什么?两步,不多不少
它只改两个字段,其余全不动:
- limit ← position:把“最多能读多少”设为“刚刚写到了哪”,即有效数据边界
- position ← 0:让下一次 get() 从缓冲区开头开始读
- capacity 不变、底层数组不变、mark 被清为 -1(不可 reset)
什么时候必须调用 flip()?
只要完成写入、准备读取,就必须调。典型场景包括:
- 用
channel.read(buffer)接收网络数据后,要解析内容 - 手动
put()写入字节、字符串或结构体后,要get()提取 - 序列化对象到 buffer 后,立即反序列化
不调?get() 会从原 position(比如 5)开始读,而 limit 还是 capacity(比如 1024),轻则读到 0,重则抛 BufferUnderflowException。
常见误用与排查方法
flip 本身很简单,但错用后果隐蔽:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 重复调用
flip()→ position=0, limit=0 →hasRemaining()返回 false,读不到任何数据 - 写完又调了
clear()或rewind()再 flip → 有效数据被覆盖或指针错位 - 读取前不检查
buffer.position() != buffer.limit(),误以为一定有数据
调试时直接打印三值最可靠:System.out.printf("pos=%d, lim=%d, cap=%d%n", buf.position(), buf.limit(), buf.capacity());
和 clear()、rewind() 的关键区别
别靠名字猜行为,看实际效果:
-
flip():写完→读,
limit=旧position; position=0 -
clear():读完→重写,
position=0; limit=capacity(丢弃全部已读/已写逻辑) -
rewind():读一半想重来,
position=0; limit不变(适合反复解析同一段)
选错方法,轻则逻辑错乱,重则数据丢失或越界异常。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










