Buffer源码解析
Buffer的demo请看转载自:https://www.cnb
logs.com/tankaixiong/p/3949421.html
class="java">/**
* 一个特定基元类型数据的容器。
* 缓冲器是一个特定的线性、有限的元素序列的原始类型。除了内容之外,。
* 缓冲区的基本属性是其容量(capacity)、限制(limit)和位置(position)。
*
* capacity:缓冲区的容量是它包含的元素的数量。缓冲区的容量从不为负,也从不改变。
* limit:缓冲区的limit是应该的第一个元素的索引。也从不为负,小于其capacity。
* position:缓冲区的位置是下一个元素的索引。从不为负,小于它的limit。
*
* 每个非布尔基元类型都有这个类的一个子类。
* 包括(ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer,DoubleBuffer)
*
* 这个类的每个子类定义了两个类别的get和put操作,
*
* 缓冲区是线程不安全,可由多个并发线程使用。如果一个缓冲区将被多个线程使用,然后访问缓冲区。
* 应该通过适当的同步来控制。
*
*/
public abstract class Buffer {
//遍历和分割元素的spliterator的特性。保存在缓冲区
static final int SPLITERATOR_CHARACTERISTICS =
Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
//不变量:标记(mark) <= 位置(position) <= 极限(limit) <= 容量(capacity)。
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;
//仅由直接缓冲区使用
//注意:在JNI GetDirectBufferAddress中提升速度。
long address;
//创建一个具有给定标记、位置、限制和容量的新缓冲区,检查后不变量。
Buffer(int mark, int pos, int lim, int cap) {
if (cap < 0)
throw new IllegalArgumentException("Negative capacity: " + cap);
this.capacity = cap;
limit(lim);
position(pos);
if (mark >= 0) {
if (mark > pos)
throw new IllegalArgumentException("mark > position: ("
+ mark + " > " + pos + ")");
this.mark = mark;
}
}
//返回该缓冲区的容量
public final int capacity() {
return capacity;
}
//返回该缓冲区的位置
public final int position() {
return position;
}
/**
* 设置此缓冲区的位置。如果标记被定义并且大于新的位置然后被丢弃
* 新位置:必须是非负数且不大于当前的限制
*/
public final Buffer position(int newPosition) {
if ((newPosition > limit) || (newPosition < 0))
throw new IllegalArgumentException();
position = newPosition;
if (mark > position) mark = -1;
return this;
}
//返回该缓冲区的限制
public final int limit() {
return limit;
}
public final Buffer limit(int newLimit) {
if ((newLimit > capacity) || (newLimit < 0))
throw new IllegalArgumentException();
limit = newLimit;
if (position > limit) position = limit;
if (mark > limit) mark = -1;
return this;
}
//在其位置设置此缓冲区的标记
public final Buffer mark() {
mark = position;
return this;
}
//将此缓冲区的位置重置为先前标记的位置。调用此方法既不更改也不丢弃标记的值
public final Buffer reset() {
int m = mark;
if (m < 0)
throw new InvalidMarkException();
position = m;
return this;
}
//清除缓存区,恢复默认值,将limit值定为capacity的值
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
//重置缓存区,limit=position(上次写到的位置),position=0(重置为0)
//也可以认为,是将Buffer的写模式,换成读模式,从数组起始处开始读
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
//返回当前位置和限制之间的元素个数。
//如果缓存区中的数据已经被全部读取完毕,limit-position=0
public final int remaining() {
return limit - position;
}
//说明当前位置和极限之间是否存在任何元素。若有,返回为true
public final boolean hasRemaining() {
return position < limit;
}
public abstract boolean isReadOnly();
//说明该缓冲区是否由可访问数组支持。
public abstract boolean hasArray();
public abstract Object array();
public abstract int arrayOffset();
//缓存区是否为直接值
public abstract boolean isDirect();
}