主要有如下两种方式建立缓冲区:java
一、调用allocate方法数组
二、调用wrap方法缓存
咱们将以charBuffer为例,阐述各个方法的含义;spa
调用allocate方法实际上会返回new HeapCharBuffer(capacity, capacity)对象;code
缓存空间存储在CharBuffer类的成员属性char[] hb数组里,即JVM堆里;对象
以下示例,建立了一个容量大小为10的CharBuffer:blog
CharBuffer bf = CharBuffer.allocate(10);
allocate方法其实比较简单,不过有点须要注意的是,allocate方法除了能够分配JVM堆空间,还能够分配直接内存空间(如ByteBuffer,能够调用allocateDirect方法分配直接内存),其内部是经过调用unsafe.allocateMemory方法实现直接内存分配的,该空间不在JVM堆内部,后续会作更加详细的说明;不过能够稍微提醒一点,若是是直接内存空间的话,调用hasArray()方法会返回false;ip
调用wrap方法实际上会也会返回new HeapCharBuffer(array, offset, length)对象;内存
与allocate方法的区别是,它的缓存存储空间是外部传入的;ci
以下示例,建立了一个容量大小为10的CharBuffer:
char[] myArray = new char[10]; CharBuffer charbuffer = CharBuffer.wrap(myArray);
另外,wrap还有一个重载方法:带offset和length做为参数的wrap()方法,以下是该方法的一个示例:
char[] myArray = new char[10]; CharBuffer charbuffer = CharBuffer.wrap (myArray, 2, 3);
以上代码将会建立一个position = 2, limit = 5, capacity = 10的Buffer;
主要有如下三种方式复制缓冲区:
一、调用duplicate方法
二、调用asReadOnlyBuffer方法
三、调用slice方法
咱们将以charBuffer为例,阐述各个方法的含义;
调用duplicate方法实际上会建立原缓存区的一个拷贝,不是深拷贝,是浅拷贝,什么意思呢,就是这两个缓存区会共享数据元素,但每一个缓存区的上界、容量、位置等属性是各自独立的;
修改其中一个缓存区的元素会影响另外一个拷贝缓存区,以下示例:
CharBuffer charbuffer1 = CharBuffer.allocate(10); CharBuffer charbuffer2 = charbuffer1.duplicate(); charbuffer1.put('a').put('b').put('c'); charbuffer1.flip(); System.out.println(charbuffer1); System.out.println(charbuffer2);
charbuffer2缓存区复制了charbuffer1缓存区,至始至终咱们只操做charbuffer1缓存区,最后打印的时候,却发现charbuffer2缓存区里已经有了charbuffer1缓存区的数据,结果打印以下:
调用asReadOnlyBuffer方法会生成一个只读缓存区,与调用duplicate方法基本一致,惟一的区别是这个缓存区是只读的,若对其进行put操做的话,会抛出ReadOnlyBufferException;
以下示例:
CharBuffer charbuffer1 = CharBuffer.allocate(10); CharBuffer charbuffer2 = charbuffer1.asReadOnlyBuffer(); charbuffer1.put('a').put('b').put('c'); charbuffer1.flip(); System.out.println(charbuffer1); System.out.println(charbuffer2); charbuffer2.put('c');//ReadOnlyBufferException
输出结果:
slice方法实际上是用于分割缓存区的,该方法建立了一个从原始缓冲区的当前位置开始的新缓冲区,而且其容量是原始缓冲区的剩余元素数量(limit-position);
该缓存区与原始缓存区共享一段序列;
以下示例:
一、咱们先建立一个容量为10的缓存区charbuffer1
CharBuffer charbuffer1 = CharBuffer.allocate(10);
此时:mark = -1; position = 0; limit = 10; capacity = 10;
二、修改charbuffer1的position和limit值
charbuffer1.position(2).limit(5);
此时:mark = -1; position = 2; limit = 5; capacity = 10;
三、调用slice方法,对charbuffer1缓存区进行分割
CharBuffer charbuffer2 = charbuffer1.slice();
此时:
charbuffer1:mark = -1; position = 2; limit = 5; capacity = 10;
charbuffer2:mark = -1; position = 0; limit = 3; capacity = 3;
《Java NIO》