capacity是缓冲区总容量且不可变,limit是动态的读写边界;capacity由allocate()指定并恒定,limit随flip()等操作变化以控制实际可操作数据范围。

capacity 是缓冲区的总容量,一旦创建就不能改变;limit 是当前可读/写数据的边界,它决定了你实际能操作多少数据。
capacity:缓冲区的“物理大小”
capacity 表示缓冲区底层数组能容纳的元素总数,由 allocate() 方法指定,比如 ByteBuffer.allocate(1024) 创建的 buffer,capacity 就是 1024。这个值在 buffer 生命周期内恒定不变,就像一个固定大小的盒子,不能伸缩。
你可以用 buffer.capacity() 获取它,但无法通过 API 修改它——想改容量?只能新建一个 buffer。
limit:当前操作范围的“逻辑上限”
limit 不是固定的,它随 buffer 的状态(读/写模式)动态变化,用来标记“数据截止到哪”,直接影响 get() 和 put() 的行为:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 刚分配或 clear() 后,limit == capacity,表示整个空间都可写
- flip() 后,limit 被设为当前 position(即写入了多少字节),表示“有多少数据可读”
- compact() 后,limit 被设为 capacity - 已读走的字节数,为后续继续写留出空间
配合 position 理解三者关系
buffer 的核心是三个指针:position(当前位置)、limit(操作上限)、capacity(总容量)。它们始终满足:0 ≤ position ≤ limit ≤ capacity。
举个例子:一个 capacity=10 的 ByteBuffer
- 初始:position=0, limit=10, capacity=10 → 可写 10 字节
- 写入 6 字节后:position=6, limit=10, capacity=10
- 调用 flip():position=0, limit=6, capacity=10 → 可读前 6 字节
- 读取 2 字节后:position=2, limit=6, capacity=10 → 剩余 4 字节可读
常见误区提醒
limit 不是“已使用量”,也不是“剩余空间”。它是明确的访问边界:
- put() 只允许写到 position BufferOverflowException
- get() 只允许读到 position BufferUnderflowException
- 不要把 limit 当作“已写入长度”——那是 position 在写模式下的含义;也不当作“剩余容量”——那是 capacity − position
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










