java.nio.ByteBuffer的 capacity, limit, position, mark
java.nio.ByteBuffer的 capacity, limit, position, mark
- Capacity(容量)
定义:缓冲区的总容量,即缓冲区中可以容纳的元素的数量。这个容量在缓冲区创建时被设定,并且之后不能被改变。
用途:它定义了缓冲区可以容纳多少数据。一旦缓冲区被分配,其容量就固定了。 - Limit(限制)
定义:第一个不应该被读或写的元素的索引,换句话说,是缓冲区的当前终点。
用途:在写模式下,limit 等于 capacity(表示你不能再往缓冲区中写数据了)。在读模式下,limit 会被设置为某个小于 capacity 的值,表示有多少数据是可读的。limit 可以被改变以反映缓冲区中实际数据的数量。 - Position(位置)
定义:下一个要被读或写的元素的索引。
用途:它指定了下一个操作(读或写)发生的位置。当从缓冲区读取数据时,position 会自动增加,指向下一个可读的数据。当向缓冲区写入数据时,position 同样会自动增加,指向下一个要写入的位置。 - Mark(标记)
定义:一个备忘位置,通过调用 mark() 方法可以设置。
用途:在某些操作之后,你可能想回到某个特定的位置,这时就可以使用 mark() 方法来标记当前的位置。之后,无论 position 走到哪里,你都可以通过调用 reset() 方法来回到 mark 标记的位置。注意,mark 是可选的,并且只有在 position 被改变之前,它才是有效的。
初始值: limit
与capacity
初始值相同, position
初始是0, mark
是-1
从测试代码可看出: limit
与capacity
初始值相同, position
初始是0, mark
是-1
测试代码
import java.nio.ByteBuffer;
public class TestByteBuffer2409172015 {
public static boolean pln=true;
public static void pln(Object...oAr) {
if(pln)for(Object o:oAr)System.out.println(o);
}
public static void main(String...arguments) {
ByteBuffer bbf = ByteBuffer.allocate(102400);
pln(bbf);
pln("bbf.capacity()"+bbf.capacity());
pln("bbf.limit()"+bbf.limit());
pln("bbf.position()"+bbf.position());
pln("bbf.mark()"+bbf.mark());
}
}
结果:
java.nio.HeapByteBuffer[pos=0 lim=102400 cap=102400]
bbf.capacity()102400
bbf.limit()102400
bbf.position()0
bbf.mark()java.nio.HeapByteBuffer[pos=0 lim=102400 cap=102400]
可看出:
实现类是: java.nio.HeapByteBuffer
limit
与capacity
初始值相同
position
初始是0
mark()方法不是返回mark属性的值, 而是设置mark=position
, 与reset()
方法配合使用, mark
初始值是-1
,在不调用mark()
方法就调用reset()
方法时,会报错
从源码看出: limit
与capacity
初始值相同, position
初始是0, mark
是-1
这四个属性定义在ByteBuffer的父类 java.nio.Buffer中
private int mark = -1;
private int position = 0;
private int limit;
private final int capacity;
mark
初始值是-1 , position
初始值是0
ByteBuffer的两个静态工厂方法
public static ByteBuffer allocateDirect(int capacity) {
return new DirectByteBuffer(capacity);
}
public static ByteBuffer allocate(int capacity) {
if (capacity < 0)
throw createCapacityException(capacity);
return new HeapByteBuffer(capacity, capacity, null);
}
allocate(int capacity)
方法 new一个继承自ByteBuffer
的HeapByteBuffer
类, capacity属性与limit属性值都来自capacity参数值allocateDirect(int capacity)
new一个DirectByteBuffer
类 extendsMappedByteBuffer
extendsByteBuffer
DirectByteBuffer(int cap) { // package-private super(-1, 0, cap, cap, null); boolean pa = VM.isDirectMemoryPageAligned(); int ps = Bits.pageSize(); long size = Math.max(1L, (long)cap + (pa ? ps : 0)); Bits.reserveMemory(size, cap); long base = 0; try { base = UNSAFE.allocateMemory(size); } catch (OutOfMemoryError x) { Bits.unreserveMemory(size, cap); throw x; } UNSAFE.setMemory(base, size, (byte) 0); if (pa && (base % ps != 0)) { // Round up to page boundary address = base + ps - (base & (ps - 1)); } else { address = base; } try { cleaner = Cleaner.create(this, new Deallocator(base, size, cap)); } catch (Throwable t) { // Prevent leak if the Deallocator or Cleaner fail for any reason UNSAFE.freeMemory(base); Bits.unreserveMemory(size, cap); throw t; } att = null;
super(-1, 0, cap, cap, null);
这句看出capacity
与limit
初始值相同
从clear()
方法也可看出: limit
与capacity
初始值相同, position
初始是0, mark
是-1
public Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;