在NIO技术的缓冲区中,存在4个核心技术点,分别是:
·capacity(容量)
·limit(限制)
·position(位置)
·mark(标记)
这4个技术点之间值的大小关系如下:
0≤mark≤position≤limit≤capacity
首先介绍一下缓冲区的capacity,它代表包含元素的数量。缓冲区的capacity不能为负数,并且capacity也不能更改。
int capacity()方法的作用:返回此缓冲区的容量。
示例代码如下:
public class Test1 { public static void main(String[] args) { byte[] byteArray = new byte[] { 1, 2, 3 }; short[] shortArray = new short[] { 1, 2, 3, 4 }; int[] intArray = new int[] { 1, 2, 3, 4, 5 }; long[] longArray = new long[] { 1, 2, 3, 4, 5, 6 }; float[] floatArray = new float[] { 1, 2, 3, 4, 5, 6, 7 }; double[] doubleArray = new double[] { 1, 2, 3, 4, 5, 6, 7, 8 }; char[] charArray = new char[] { 'a', 'b', 'c', 'd' }; ByteBuffer bytebuffer = ByteBuffer.wrap(byteArray); ShortBuffer shortBuffer = ShortBuffer.wrap(shortArray); IntBuffer intBuffer = IntBuffer.wrap(intArray); LongBuffer longBuffer = LongBuffer.wrap(longArray); FloatBuffer floatBuffer = FloatBuffer.wrap(floatArray); DoubleBuffer doubleBuffer = DoubleBuffer.wrap(doubleArray); CharBuffer charBuffer = CharBuffer.wrap(charArray); System.out.println("bytebuffer=" + bytebuffer.getClass().getName()); System.out.println("shortBuffer=" + shortBuffer.getClass().getName()); System.out.println("intBuffer=" + intBuffer.getClass().getName()); System.out.println("longBuffer=" + longBuffer.getClass().getName()); System.out.println("floatBuffer=" + floatBuffer.getClass().getName()); System.out.println("doubleBuffer=" + doubleBuffer.getClass().getName()); System.out.println("charBuffer=" + charBuffer.getClass().getName()); System.out.println(); System.out.println("bytebuffer.capacity=" + bytebuffer.capacity()); System.out.println("shortBuffer.capacity=" + shortBuffer.capacity()); System.out.println("intBuffer.capacity=" + intBuffer.capacity()); System.out.println("longBuffer.capacity=" + longBuffer.capacity()); System.out.println("floatBuffer.capacity=" + floatBuffer.capacity()); System.out.println("doubleBuffer.capacity=" + doubleBuffer.capacity()); System.out.println("charBuffer.capacity=" + charBuffer.capacity()); } }
程序运行结果如下:
bytebuffer=java.nio.HeapByteBuffer shortBuffer=java.nio.HeapShortBuffer intBuffer=java.nio.HeapIntBuffer longBuffer=java.nio.HeapLongBuffer floatBuffer=java.nio.HeapFloatBuffer doubleBuffer=java.nio.HeapDoubleBuffer charBuffer=java.nio.HeapCharBuffer bytebuffer.capacity=3 shortBuffer.capacity=4 intBuffer.capacity=5 longBuffer.capacity=6 floatBuffer.capacity=7 doubleBuffer.capacity=8 charBuffer.capacity=4
由于ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer是抽象类,因此wrap()就相当于创建这些缓冲区的工厂方法,在源代码中创建的流程示例如图1-8所示。
图1-8 创建流程
从源代码中可以发现,通过创建HeapByteBuffer类的实例来实现创建ByteBuffer类的实例。因为ByteBuffer与HeapByteBuffer是父子类的关系,所以在将HeapByteBuffer类的对象赋值给数据类型为ByteBuffer的变量时产生多态关系。
ByteBuffer类缓冲区的技术原理就是使用byte[]数组进行数据的保存,在后续使用指定的API来操作这个数组以达到操作缓冲区的目的,示例代码如图1-9所示。
在HeapByteBuffer类的构造方法中,使用代码super(-1,off,off+len,buf.length,buf,0)调用父类的构造方法将字节数组buf传给父类ByteBuffer,而且子类HeapByteBuffer还重写了父类ByteBuffer中的大部分方法,因此,在调用HeapByteBuffer类的API时,访问的是父类中的buf字节数组变量,在调用API处理buf字节数组中的数据时,执行的是HeapByteBuffer类中重写的方法。
图1-9 HeapByteBuffer类构造方法的流程
从源代码中可以了解到,缓冲区存储的数据还是存储在byte[]字节数组中。使用缓冲区与使用byte[]字节数组的优点在于缓冲区将存储数据的byte[]字节数组内容与相关的信息整合在1个Buffer类中,将数据与缓冲区中的信息进行了整合,并进行了封装,这样便于获得相关的信息及处理数据。
capacity代表着缓冲区的大小,效果如图1-10所示。
图1-10 容量图示
缓冲区中的capacity其实就是buf.length属性值。