【写在前面】 所谓读源码,三分看代码,七分看注释。英语不好怎么办,我帮你翻译!
package java.nio
public abstract class Buffer
extends Object
一种指定基本类型的数据的容器。
Buffer是一个线性,有限的指定基本类型的元素序列。除了它的内容,buffer的其他属性还有capacity,limit,position:
- Capacity是buffer包含元素的个数,buffer的capacity绝不会是个负数,也不会改变。
- Limit是第一个不能读/写的元素的索引(译者注:内置数组的下标),buffer的limit绝不会是负数,也不可能大于capacity(最多等于)。
- Position是第一个可以读/写的元素的索引。Buffer的position绝不会是个负数,也不会超过limit(最多等于)。
这个类对应每种基本类型都有一个子类,除了boolean类型。
Transferring data(数据传输)
这个类的每个子类对get和put都定义了两种类型的操作:
- Relative(相对)操作从当前的position读或写一个或多个元素,然后position会增加传输的元素的数量。如果要求的传输超过了limit,那么一个相对的get操作就会抛出BufferUnderflowException,一个相对的put操作就会抛出 BufferOverflowException,这两种情况下,数据不会传输。(译者注:position也不会改变)。
- Absolute(绝对)操作采用显式的元素索引(去读或写元素),不会影响到position,如果这个索引超过了limit,那么绝对的get和put操作会抛出一个IndexOutOfBoundsException。
数据当然也可以由适当的channel的I/O操作传输进/出一个buffer,在这种情况下,都是属于相对操作的(译者注:也就是会影响position)。
Marking and resetting(标记和重置)
一个buffer的mark(标记)就是在调用reset方法,position会重置为一个位置的索引。Mark不是一直都是定义好了的,但是在定义mark的时候,它绝不会是个负数,也不会大于position。如果mark已经定义好了,当position和limit被调整到比mark小的时候,mark就会被废弃 (译者注:被置为-1)。如果mark还没定义,调用reset方法将会导致InvalidMarkException抛出。
Invariants(不变式,恒成立的)
下面的不变式适用于:mark,position,limit,capacity:
0 <= mark <= position <= limit <= capacity
一个新创建的buffer总是position=0,mark未定义(译者注:值为-1)。初始化的limit可能为0,也可能为其他值,取决于buffer的类型和构造它的方式。新分配的buffer的每个元素都被初始化为0。
Clearing, flipping, and rewinding(清空,翻转,和倒带)
除了一些访问position,limit,capacity值和标记和重置的方法。这个类也在buffers上定义了下列一些操作:
- clear 让buffer准备好(接收)一个channel读操作或者相对的put操作(产生的)序列:它会设置limit为capacity,position为0。
- filp 让buffer准备好一个channel写操作或者相对的get操作所需要的序列:它会设置limit为当前position,position为0.
- rewind 让buffer准备好重新读它已经包含的数据:它会设置limit不变,position为0。
Read-only buffers(只读缓冲区)
所有的buffer都可读,但不是所有buffer都可写。每个buffer的可变方法都被指定为可选操作,当在只读buffer对象上调用这些方法时,会抛出ReadOnlyBufferException。一个只读buffer不允许它的内容被更改,但是它的mark,position,limit是可变的。一个buffer是否只读可以由调用isReadOnly方法确定。
Thread safety(线程安全)
在多线程并发下使用的buffer不是线程安全的。如果一个buffer被超过一个线程使用,那么访问这个buffer就应该进行适当的同步控制。
Invocation chaining(链式调用)
这个类的方法如果没有返回值,那么就会返回(调用这些方法的)buffer对象本身。它允许方法的调用成为链式,举个例子,下列这些语句序列:
b.flip();
b.position(23);
b.limit(42);
可以被替换成单独的,更紧凑的语句:
b.flip().position(23).limit(42);
Since:1.4