那么接下来还是一个虚类ByteBuffer
先来对代码前英文注释的一些翻译
这个类定义了六类基于byte buffer的操作
绝对和相对的get、put操作,用来读写单个bytes(我很好奇为什么是 single bytes)
相对的bulk get方法,用来把当前buffer中邻近的一些字节传递到一个数组(array)里
相对的bulk put方法,用来把一个数组(array)或者buffer中邻近的字节传递到当前buffer中
绝对或者相对的getChar putChar用来读写其他原始类型,以特定字节顺序将它们转换为字节序列和从字节序列转换它们
为了允许byte buffer被视为包含其他原始类型的buffer,用来创造视图buffer
一个用来压缩buffer的方法
Byte buffer创建可以为buffer的内容分配空间,也可以通过wrap一个已有的byte数组到buffer里
接下来是直接的buffer和不直接的buffer
一个buffer要么是直接的要么是非直接的。对于直接的buffer,jvm会尽力让基于直接buffer的本地io效率更高。因此,会避免在每次调用底层原生io之前复制buffer的内容到中间buffer,也避免在每次调用底层原生io之前从中间buffer复制内容到buffer。
直接的buffer可以通过调用该类的allocateDirect工厂方法。对比非直接的buffer,通过这个方法返回的buffer通常有更高的分配和析构成本。直接的buffer的内容通常在进行垃圾回收的堆外,因此它们对内存回收后的内存曲线变化没有太大影响。因此推荐在数据大、存活长并且主要用来对底层系统io操作的时候使用。通常只有在程序性能上能够得到可观收益时才使用直接buffer。
一个直接的byte buffer同样可以由内存中直接的文件区域创建。Jvm的一种实现会可选性的提供通过原始代码jni创建直接的byte buffer。如果这些buffer类中的一个实例引用了不可访问的内存区域,那么对这些内存的访问将不会改变buffer的内容,并且会在访问时或访问后的一段时间内造成不明异常
一个buffer是直接的还是不直接的取决于调用的方式。提供此方法是为了在性能关键代码中完成显式缓冲区管理
该类定义了用来读写原始类型的方法。原始数据被按照buffer里的顺序转化成字节序列,可以通过order方法进行修改。特定的字节顺序可以用ByteOrder类的实例来表示。一个byte buffer中的原始顺序总可以用ByteOrder表示
为了访问由不同类型合成的二进制数据,该类提供了一系列的绝对和相对的get和put方法为每种类型。对于32为的浮点型,该类定义了
* <blockquote><pre>
* float {@link #getFloat()}
* float {@link #getFloat(int) getFloat(int index)}
* void {@link #putFloat(float) putFloat(float f)}
* void {@link #putFloat(int,float) putFloat(int index, float f)}</pre></blockquote>
相应的方法也定义了其他原始类型的比如char short int long double。绝对的get和put方法中的index参数是对字节而言而不是对原来放入时的类型而言
为了访问到相同类型的二进制数据,该类定义了方法能够对于给定的buffer创建视图。一个视图buffer类似于其他由byte buffer支撑的buffer。改变原来byte buffer的内容会在视图中生效,反之亦然。两个buffer的position limit mark值都是不相关的。例如asFloatBuffer()方法,基于byte buffer调用这个方法创建一个FloatBuffer的实例,相应的视图创建方法也提供了给其他原始类型。
与上述类型特定的<i> get </ i>和<i> put </ i>方法相比,View缓冲区具有三个重要优势。
一个视图buffer基于字节排序而不是基于输入时特定的类型
视图缓冲区提供相对批量<i> get </ i>和<i> put </ i>方法,这些方法可以在缓冲区和数组或相同类型的某个其他缓冲区之间传输连续的值序列
视图buffer有可能变得更高效因为它可以是直接的,当且仅当支持它的byte buffer也是直接的
视图缓冲区的字节顺序固定为创建视图时其字节缓冲区的字节顺序。