把这四个属性想象成一段可伸缩的“卷尺”就一目了然:
1. capacity(容量)
卷尺的总长度,出厂时就固定死,永远不变。它告诉你:这块缓冲区最大能装多少字节。
2. limit(边界)
当前“有效刻度”的终点。
- 写模式:limit = capacity,表示你可以一直写到卷尺尽头。
- 读模式:执行 `flip()` 后,limit 被设成刚才写完的位置,表示“只读到这儿”。
任何读/写操作都不能越过 limit,否则抛异常。
3. position(游标)
卷尺上小滑块的当前位置。
- 每读/写一个字节,滑块就往前进一格。
- 初始为 0;最大可到 limit-1。
4. mark(书签)
你在滑块处夹一个小夹子(调用 `mark()`)。
之后无论滑块滑到哪儿,都可以一句 `reset()` 让它瞬间回到夹子位置。
如果不设夹子,mark 就是 -1(无效)。
---
四者大小关系
```
0 ≤ mark ≤ position ≤ limit ≤ capacity
```
---
一张图秒懂(逻辑视图)
```
[0 ... mark ... position ... limit ... capacity)
```
- 可读/写区间:`position` 到 `limit-1`
- 已读/写区间:`0` 到 `position-1`
---
常用模式切换
动作 position limit 说明
刚 allocate 0 capacity 准备写
写完后 flip() 0 原 position 切换到读模式
读完后 clear() 0 capacity 清空,回到写模式
---
一句话总结:
- capacity 是“总长度”;
- limit 是“当前可用终点”;
- position 是“光标”;
- mark 是“可回退的书签”。
mark不能大于position吗?
不能。
在 `Buffer` 的源码里,`mark()` 的实现:
```java
public final Buffer mark() {
mark = position;
return this;
}
```
也就是说,mark 永远被设置成调用 `mark()` 那一刻的 `position` 值。
随后如果继续读/写,`position` 会向前移动,而 `mark` 保持原位,于是自然满足:
```
0 ≤ mark ≤ position ≤ limit ≤ capacity
```
如果之后你用 `reset()` 试图回到 mark,但发现之前调用过 `position(newPos)` 且 `newPos < mark`,就会立即抛 `InvalidMarkException`——这进一步说明 mark 必须不大于当前 position。
1678

被折叠的 条评论
为什么被折叠?



