clear()丢弃未读数据并重置指针,compact()保留未读数据并前移;前者适用于无需残留数据的全新写入,后者适用于需续写未读内容的场景。

clear() 和 compact() 都是用来让 ByteBuffer 重新进入“可写状态”的方法,但它们处理未读数据的方式完全不同——关键在于:你是否还需要那些还没读完的数据。
clear():丢弃未读数据,从头开始写
调用 clear() 后,Buffer 的指针被重置为初始写入态:position = 0,limit = capacity,mark = -1。底层字节数组里的内容完全不变,只是逻辑上“假装没写过”,后续 channel.read(buffer) 会直接覆盖原有内容。
适用场景:
- 你已经处理完当前有效数据(哪怕只读了一部分),剩下的字节无意义
- 下一批要写入的是全新数据,和之前的内容无关
- 追求简单高效,不关心残留数据
compact():保留未读数据,挪到开头再续写
compact() 会把 position 到 limit 之间的未读数据(即还没被 get() 拿走的部分)复制到缓冲区起始位置,然后将 position 设为这段数据的末尾,limit 设为 capacity。相当于“腾出前面空间,把剩的往前搬”。
适用场景:
- 读取不完整(比如只读了前几个字节),但后面的数据还要继续处理
- 需要在保留旧数据的前提下追加新数据(如解析分块协议、拼接不完整包)
- 避免因 clear() 导致数据丢失,又不想手动拷贝数组
一个直观对比(容量为 10 的 ByteBuffer)
假设写入 "HELLO123"(8 字节),flip() 后读了 "HE",此时:
position = 2,limit = 8,未读内容是 "LLO123"
- clear() 后:position=0,limit=10,原数组仍是 [H,E,L,L,O,1,2,3,?,?],但下次 write 会从头覆盖
- compact() 后:数组变成 [L,L,O,1,2,3,?, ?, ?, ?],position=6,limit=10,新数据将从下标 6 开始写入
怎么选?看数据要不要留
如果未读数据可以扔,用 clear();如果还得接着用,必须用 compact()。两者都不改变 capacity,也不清空底层内存——只是调整指针或移动有效字节。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











