ByteBuffer 的基類是 Buffer , Buffer 是一個抽象類,定義了4個基本的屬性:
// Invariants: mark <= position <= limit <= capacity
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;
ByteBuffer 在此基礎(chǔ)上又定義了兩個成員:
final byte[] hb; // Non-null only for heap buffers
final int offset;
從注釋可以看出,hb 是只有heap buffer會用到,這里說的heap buffer就是 ByteBuffer 的子類 HeapByteBuffer ,這也是我們后面的閱讀重點,因為大部分時候我們使用ByteBuffer 其實就是用的 HeapByteBuffer
ByteBuffer 的初始化方式主要有很多,因為其核心屬性是final byte[] hb , 所以初始化主要就是分為兩類:
一類是由ByteBuffer 的 allocate 方法來初始化:
public static ByteBuffer allocate(int capacity) {
if (capacity < 0)
throw new IllegalArgumentException();
return new HeapByteBuffer(capacity, capacity);
}
我們可以看到,這里直接new出來了一個HeapByteBuffer對象。
另一類是提前初始化好的byte[],作為參數(shù)傳進構(gòu)造函數(shù)來初始化:
ByteBuffer(int mark, int pos, int lim, int cap, // package-private
byte[] hb, int offset){
super(mark, pos, lim, cap);
this.hb = hb;
this.offset = offset;
}
或者通過wrap方法,生成一個HeapByteBuffer:
public static ByteBuffer wrap(byte[] array,
int offset, int length){
try {
return new HeapByteBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
throw new IndexOutOfBoundsException();
}
}
ByteBuffer 除了繼承了Buffer類之外,還實現(xiàn)了Comparable接口,兩個ByteBuffer比較時,比較的是ByteBuffer中剩余的byte數(shù)組,從當前的position開始,一直比較到最后一個byte:
public int compareTo(ByteBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
for (int i = this.position(), j = that.position(); i < n; i++, j++) {
int cmp = compare(this.get(i), that.get(j));
if (cmp != 0)
return cmp;
}
return this.remaining() - that.remaining();
}
private static int compare(byte x, byte y) {
return Byte.compare(x, y);
}
ByteBuffer 還實現(xiàn)了equals方法,提供了比較兩個Buffer的功能:
public boolean equals(Object ob) {
//如果是同一個對象,那么相等
if (this == ob)
return true;
//如果比較對象不是ByteBuffer對象,那么肯定不相等
if (!(ob instanceof ByteBuffer))
return false;
ByteBuffer that = (ByteBuffer)ob;
//如果兩個Buffer剩余的byte數(shù)目不一樣多,肯定不相等
if (this.remaining() != that.remaining())
return false;
//從Buffer的末尾開始比較
int p = this.position();
for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
if (!equals(this.get(i), that.get(j)))
return false;
return true;
}
private static boolean equals(byte x, byte y) {
return x == y;
}