capacity是缓冲区总容量且固定不变,limit是当前有效数据边界且可变;capacity决定最大容量,limit标识可读写范围终点,且始终满足limit≤capacity。

capacity 是缓冲区的总容量,limit 是当前有效数据边界。两者都表示索引位置,但作用不同:capacity 固定不变,代表底层数组能容纳的最大元素数;limit 可变,标识“可读或可写范围的终点”,即下一个越界的位置。
capacity:缓冲区的硬性上限
它在 Buffer 创建时就确定,之后无法修改。无论是通过 ByteBuffer.allocate(1024) 还是 ByteBuffer.wrap(array) 初始化,capacity 都等于底层数组长度(或你指定的大小)。它不随读写操作变化,也不区分读写模式——只说明“最多能装多少”。
- 必须是非负整数
- 初始化后不可调整(wrap 包裹已有数组时,capacity 就是数组 length)
- 比如
ByteBuffer.allocate(8)→ capacity 永远是 8
limit:动态划定的操作边界
limit 决定了当前 Buffer 在读或写时“能用到哪儿”。它不是固定值,会随状态转换(如 flip、clear、compact)而改变:
- 刚创建或调用
clear()后,limit = capacity(整个空间可写) - 写入若干字节后调用
flip(),limit 被设为写入结束时的 position(即有效数据长度),position 归零,准备读取 - 读取过程中,limit 不变,直到再次切换模式
- 手动调用
limit(n)可直接设值,但不能超过 capacity
二者关系:limit ≤ capacity 是硬约束
Java NIO 强制要求 limit 始终小于等于 capacity,且 position 始终介于 0 和 limit 之间。如果代码中尝试 buffer.limit(20) 而 capacity 只有 16,会抛出 IllegalArgumentException。这种设计保证了所有访问都在安全范围内。
- 常见等式:
buffer.remaining() == buffer.limit() - buffer.position() - 当 position == limit 时,表示当前模式下已无数据可读 / 无可写空间
- limit 改变通常意味着语义切换:从“我能写多少”变成“我该读多少”
理解这两个属性的关键在于跳出“数组下标”的直觉,把它们看作协作控制数据流动的阀门:capacity 是管道直径,limit 是当前闸门位置,而 position 是探针尖端。










