JDK8源码阅读笔记
切换暗/亮/自动模式 切换暗/亮/自动模式 切换暗/亮/自动模式 返回首页

ByteBuffer




字节缓冲区。
此类定义了字节缓冲区上的六类操作:

  • 读取和写入单个字节的绝对和相对getput方法。
  • 相对批量get方法,将连续的字节序列从此缓冲区转移到数组中。
  • 将连续的字节序列从字节数组或某个其他字节缓冲区转移到该缓冲区的相对批量put方法。
  • 绝对和相对的getput方法用于读取和写入其他原始类型的值,将它们转换为特定字节顺序的字节序列。
  • 方法用于创建视图缓冲区,这允许一个字节缓冲区被视作包含其他原始类型的值的缓冲区。
  • 压缩复制切片字节缓冲区的方法。

字节缓冲区可以通过分配(为缓冲区的内容分配空间)或将现有字节数组包装到缓冲区中来创建。

直接缓冲区与非直接缓冲区
一个字节缓冲区要么是直接的,要么是不是直接的。对于一个直接字节缓冲区,Java虚拟机会尽最大努力直接在其上执行本地I/O操作。也就是说,它将尝试避免在每次调用底层操作系统的本地I/O操作之前(或之后)将缓冲区的内容复制到一个中间缓冲区(或从一个中间缓冲区复制到缓冲区)。

直接字节缓冲区可以通过调用这个类的allocateDirect工厂方法来创建。这个方法返回的缓冲区在分配和释放成本上通常比非直接缓冲区要高一些。直接缓冲区的内容可能位于常规垃圾回收堆之外,因此它们对应用程序内存占用的影响可能不是很明显。因此,建议主要为大型、长期存在的缓冲区分配直接缓冲区,这些缓冲区将受到底层系统本地I/O操作的影响。通常情况下,最好只有在直接缓冲区能够在程序性能上带来可衡量的提升时,才分配直接缓冲区。

还可以通过将文件的区域直接映射到内存中来创建直接字节缓冲区。Java平台的实现可以选择性地支持通过JNI从本地代码创建直接字节缓冲区。如果这些类型的缓冲区中的一个实例引用了一个不可访问的内存区域,那么访问该区域的尝试将不会更改缓冲区的内容,并将导致在访问时或稍后引发不受检查的异常。

一个字节缓冲区是直接的还是非直接的,可以通过调用它的isDirect方法来确定。提供这个方法是为了能够在性能关键型代码中进行显式的缓冲区管理。

访问二进制数据
这个类定义了除了布尔类型之外的所有其他基本类型值读取和写入的方法。基本类型值根据缓冲区的当前字节序被转换为字节序列(或基于字节序列转换为当前字节序),当前字节序可以通过order方法获取和修改。特定的字节序由ByteOrder类的实例表示。字节缓冲区的初始字节序始终是BIG_ENDIAN(大端序)。

用于访问异构二进制数据,即不同类型值的序列,这个类为每种类型定义了一系列绝对和相对的 get 和 put 方法。例如,对于32位浮点值,这个类定义了:

  float  getFloat()
  float  getFloat(int index)
   void  putFloat(float f)
   void  putFloat(int index, float f)

本类为 char、short、int、long 和 double 类型定义了相应的方法。绝对 get 和 put 方法的索引参数是以字节为单位,而不是基于正在读取或写入的类型。

为了访问同类型二进制数据,即相同类型值的序列,这个类定义了可以创建给定字节缓冲区视图的方法。视图缓冲区实际上是另一个缓冲区,其内容由字节缓冲区支持。对字节缓冲区内容的更改将在视图缓冲区中可见,反之亦然;这两个缓冲区的位置、限制和标记值是独立的。例如,asFloatBuffer方法创建了一个FloatBuffer类的实例,它由调用该方法的字节缓冲区支持。本类为 char、short、int、long 和 double 类型定义了相应的视图创建方法。

视图缓冲区与上述特定类型的 get 和 put 方法相比具有三个重要优势:

  • 视图缓冲区的索引不是以字节为单位,而是以其值的类型特定大小为单位;
  • 视图缓冲区提供了相对的批量 get 和 put 方法,这些方法可以在缓冲区与数组或其他相同类型的缓冲区之间传输连续的值序列;
  • 视图缓冲区可能效率更高,因为如果仅当其支持的字节缓冲区是直接的,它才会是直接的。

视图缓冲区的字节序在创建视图时固定为其字节缓冲区的字节序。

调用链 这个类中没有其他返回值要返回的方法被指定为返回它们被调用的缓冲区。这允许将方法调用链接在一起。如下语句:

bb. putInt(0xCAFEBABE); 
bb. putShort(3); 
bb. putShort(45);

可以用如下单个语句替换:

bb. putInt(0xCAFEBABE).putShort(3).putShort(45);

1. final byte[] hb;

这个字段还有下面的offsetisReadOnly字段在这里声明,而不是在“Heap-X-Buffer”中声明,目的是为了减少访问这些值所需的虚拟方法调用次数,这在编码小缓冲区时尤其耗费成本。

字节数组,非空、仅适用于堆缓冲区。


2. final int offset;

偏移量。


3. boolean isReadOnly;

当前字节缓冲区是否只读。仅对堆缓冲区有效。


4. ByteBuffer(int mark, int pos, int lim, int cap, byte[] hb, int offset)

基于给出的markpositionlimitcapacity,后备数组和数组偏移量创建一个字节缓冲区。

ByteBuffer(int mark, int pos, int lim, int cap,   // 包内私有
              byte[] hb, int offset)
{
    super(mark, pos, lim, cap);
    this.hb = hb;
    this.offset = offset;
}

5. ByteBuffer(int mark, int pos, int lim, int cap)

基于给出的markpositionlimitcapacity创建一个字节缓冲区。

ByteBuffer(int mark, int pos, int lim, int cap) { // 包内私有
    this(mark, pos, lim, cap, null, 0);
}

6. public static ByteBuffer allocateDirect(int capacity)

分配一个新的直接字节缓冲区。

新缓冲区的位置将为零,其限制将为其容量,其标记将未定义,其每个元素将被初始化为零。它是否有支持数组是未指明的。

参数capacity是新缓冲区的容量(字节)。

public static ByteBuffer allocateDirect(int capacity) {
    return new DirectByteBuffer(capacity);
}

7. public static ByteBuffer allocate(int capacity)

分配一个新的字节缓冲区。

新缓冲区的位置将被设置为零,其限制将等于其容量,其标记将未定义,其所有元素将被初始化为零。它将拥有一个后备数组,并且其数组偏移量将为零。

参数capacity是新缓冲区的容量(字节)。

public static ByteBuffer allocate(int capacity) {
    if (capacity < 0)
        throw new IllegalArgumentException();
    return new HeapByteBuffer(capacity, capacity);
}

8. public static ByteBuffer wrap(byte[] array, int offset, int length)

将字节数组封装到缓冲区中。

新缓冲区将基于给定的字节数组,也就是说,对缓冲区的修改将导致数组被修改,反之亦然。新缓冲区的容量将为数组的长度,其位置将为偏移量,其限制将为偏移量加数组长度,其标记将未定义。它的支持数组将是给定的数组,其数组偏移量将为零。

参数:

  • array:将支持新缓冲区的数组
  • offset:要使用的子数组的偏移量;必须是非负的并且不大于数组的长度。新缓冲区的位置将设置为此值。
  • length:要使用的子数组的长度;必须是非负数,并且不大于 数组长度 - offset。新缓冲区的限制将被设置为 offset + length
public static ByteBuffer wrap(byte[] array,
                                int offset, int length)
{
    try {
        return new HeapByteBuffer(array, offset, length);
    } catch (IllegalArgumentException x) {
        throw new IndexOutOfBoundsException();
    }
}

9. public static ByteBuffer wrap(byte[] array)

将字节数组封装到缓冲区中。

新缓冲区将由给定的字节数组支持;也就是说,对缓冲区的修改将导致数组被修改,反之亦然。新缓冲区的容量和限制将为数组的长度,其位置将为零,其标记将未定义。它的支持数组将是给定的数组,其数组偏移量将为零。

public static ByteBuffer wrap(byte[] array) {
    return wrap(array, 0, array.length);
}

10. public abstract ByteBuffer slice();

创建一个新的字节缓冲区,其内容是这个缓冲区内容的共享子序列。
新缓冲区的内容将从这个缓冲区的当前位置开始。对这个缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。

新缓冲区的位置将为零,其容量和限制将是这个缓冲区剩余的字节数,其标记将未定义。如果这个缓冲区是直接的,新缓冲区也将是直接的,如果这个缓冲区是只读的,新缓冲区也将是只读的。


11. public abstract ByteBuffer duplicate();

创建一个新的字节缓冲区,与这个缓冲区共享内容。
新缓冲区的内容将与这个缓冲区的内容相同。对这个缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。

新缓冲区的容量、限制、位置和标记值将与这个缓冲区的完全相同。如果这个缓冲区是直接的,新缓冲区也将是直接的,如果这个缓冲区是只读的,新缓冲区也将是只读的。


12. public abstract ByteBuffer asReadOnlyBuffer();

创建一个新的只读字节缓冲区,与这个缓冲区共享内容。
新缓冲区的内容将与这个缓冲区的内容相同。对这个缓冲区内容的更改将在新缓冲区中可见;然而,新缓冲区本身是只读的,不允许修改共享的内容。两个缓冲区的位置、限制和标记值将是独立的。

新缓冲区的容量、限制、位置和标记值将与这个缓冲区的完全相同。

如果这个缓冲区本身是只读的,那么这个方法的行为与duplicate方法完全相同。


13. public abstract byte get();

相对 get 方法。读取这个缓冲区当前位置的字节,然后增加位置。


14. public abstract ByteBuffer put(byte b);

相对 put 方法(可选操作)。
将给定的字节写入此缓冲区的当前位置,然后增加位置。


15. public abstract byte get(int index);

绝对获取方法。读取给定索引处的字节。


16. public abstract ByteBuffer put(int index, byte b);

绝对 put 方法(可选操作)。
将给定的字节写入到此缓冲区给定的索引位置。


17. public ByteBuffer get(byte[] dst, int offset, int length)

相对批量获取方法。
这个方法将字节从这个缓冲区传输到给定的目标数组。如果在缓冲区中剩余的字节少于请求所需的字节,也就是说,如果 length > remaining(),那么将不会传输任何字节,并抛出BufferUnderflowException异常。

否则,这个方法将从这个缓冲区的当前位置开始,复制length长度的字节到给定数组中给定的偏移量位置。然后,这个缓冲区的位置会增加length

换句话说,以src.get(dst, off, len)形式调用这个方法,其效果与以下循环完全相同:

for (int i = off; i < off + len; i++)     
    dst[i] = src. get():

除了在执行循环之前,它首先检查这个缓冲区中是否有足够的字节,并且它的效率可能要高得多。

参数说明:

  • dst:要写入字节的数组
  • offset:数组中第一个要写入的字节的偏移量;必须是非负数,并且不大于 dst.length。
  • length:写入给定数组的最大字节数;必须是非负数,并且不大于 dst.length - offset。
public ByteBuffer get(byte[] dst, int offset, int length) {
    checkBounds(offset, length, dst.length);
    if (length > remaining())
        throw new BufferUnderflowException();
    int end = offset + length;
    for (int i = offset; i < end; i++)
        dst[i] = get();
    return this;
}

18. public ByteBuffer get(byte[] dst)

相对的批量 get 方法。 这个方法将字节从这个缓冲区传输到给定的目标数组。以src.get(a)形式调用这个方法的行为与调用src.get(a, 0, a.length)完全相同。

public ByteBuffer get(byte[] dst) {
    return get(dst, 0, dst.length);
}

19. public ByteBuffer put(ByteBuffer src)

相对的批量 put 方法(可选操作)。
这个方法将给定源缓冲区中剩余的字节传输到当前缓冲区。如果在源缓冲区中剩余的字节比这个缓冲区多,也就是说,如果src.remaining() > remaining(),那么将不会传输任何字节,并抛出BufferOverflowException异常。
否则,这个方法从给定的缓冲区复制n个字节到这个缓冲区(n = src.remaining()),从每个缓冲区的当前位置开始,然后两个缓冲区的位置都增加 n。
换句话说,以dst.put(src)形式调用这个方法的效果与以下循环完全相同:

      while (src. hasRemaining())
          dst. put(src. get()); 

除了它首先检查这个缓冲区中是否有足够的空间,并且可能效率要高得多。

public ByteBuffer put(ByteBuffer src) {
    if (src == this)
        throw new IllegalArgumentException();
    if (isReadOnly())
        throw new ReadOnlyBufferException();
    int n = src.remaining();
    if (n > remaining())
        throw new BufferOverflowException();
    for (int i = 0; i < n; i++)
        put(src.get());
    return this;
}

20. public ByteBuffer put(byte[] src, int offset, int length)

相对的批量 put 方法(可选操作)。
这个方法将字节从给定的源数组传输到这个缓冲区。如果从数组中要复制的字节多于这个缓冲区剩余的字节,也就是说,如果length > remaining(),那么将不会传输任何字节,并抛出BufferOverflowException异常。
否则,这个方法从给定数组中复制数量为length的字节到这个缓冲区,从数组中的给定偏移量开始,以及从这个缓冲区的当前位置开始。然后这个缓冲区的位置增加了 length。
换句话说,以dst.put(src, off, len)形式调用这个方法的效果与以下循环完全相同:

for (int i = off; i < off + len; i++) {
    dst.put(a[i]);
}

除了它首先检查这个缓冲区中是否有足够的空间,并且可能效率要高得多。

public ByteBuffer put(byte[] src, int offset, int length) {
    checkBounds(offset, length, src.length);
    if (length > remaining())
        throw new BufferOverflowException();
    int end = offset + length;
    for (int i = offset; i < end; i++)
        this.put(src[i]);
    return this;
}

21. public final ByteBuffer put(byte[] src)

相对的批量 put 方法(可选操作)。 这个方法将给定源字节数组的全部内容传输到这个缓冲区。以dst.put(a)形式调用这个方法的行为与调用如下方法完全相同:

      dst.put(a, 0, a.length)

源码:

public final ByteBuffer put(byte[] src) {
    return put(src, 0, src.length);
}

22. public final boolean hasArray()

判断这个缓冲区是否由一个可访问的字节数组支持。 如果这个方法返回true,那么可以安全地调用arrayarrayOffset方法。

public final boolean hasArray() {
    return (hb != null) && !isReadOnly;
}

23. public final byte[] array()

返回支持这个缓冲区的字节数组(可选操作)。
对这个缓冲区内容的修改将导致返回数组的内容被修改,反之亦然。
在调用这个方法之前,先调用hasArray方法,以确保这个缓冲区有一个可访问的支持数组。

public final byte[] array() {
    if (hb == null)
        throw new UnsupportedOperationException();
    if (isReadOnly)
        throw new ReadOnlyBufferException();
    return hb;
}

24. public final int arrayOffset()

返回这个缓冲区支持数组中第一个元素的偏移量(可选操作)。
如果这个缓冲区是由一个数组支持的,那么缓冲区位置 p 对应于数组索引 p + arrayOffset()。
在调用这个方法之前,先调用hasArray方法,以确保这个缓冲区有一个可访问的支持数组。

public final int arrayOffset() {
    if (hb == null)
        throw new UnsupportedOperationException();
    if (isReadOnly)
        throw new ReadOnlyBufferException();
    return offset;
}

25. public abstract ByteBuffer compact();

压缩这个缓冲区(可选操作)。
缓冲区当前位置和限制之间如果存在字节,这些字节被复制到缓冲区的开头。也就是说,在索引 p = position() 处的字节被复制到索引0处,索引 p + 1 处的字节被复制到索引1处,以此类推,直到索引 limit() - 1 处的字节被复制到索引 n = limit() - 1 - p。然后,缓冲区的位置被设置为 n + 1,其限制被设置为其容量。如果已定义了标记,标记将被丢弃。

缓冲区的位置被设置为已复制的字节数,而不是零,这样,这个方法的调用可以立即跟随另一个相对 put 方法的调用。

在从缓冲区写入数据后调用此方法,以防写入不完整。例如,以下循环通过缓冲区buf将字节从一个通道复制到另一个通道:

buf. clear();          // 准备缓冲区以备使用
while (in. read(buf) >= 0 || buf. position != 0) {
    buf.flip();     
    out.write(buf);     
    buf.compact();    // 如果是部分写入
}

26. public abstract boolean isDirect();

返回这个字节缓冲区是否是直接的。


27. public String toString()

返回一个字符串,总结此缓冲区的状态。

public String toString() {
    StringBuffer sb = new StringBuffer();
    sb.append(getClass().getName());
    sb.append("[pos=");
    sb.append(position());
    sb.append(" lim=");
    sb.append(limit());
    sb.append(" cap=");
    sb.append(capacity());
    sb.append("]");
    return sb.toString();
}

28. public int hashCode()

返回这个缓冲区的当前哈希码。

一个字节缓冲区的哈希码仅取决于其剩余元素;也就是说,取决于从 position() 到包括 limit() - 1 位置的元素。

因为缓冲区的哈希码是内容依赖的,所以不建议在哈希映射或类似数据结构中使用缓冲区作为键,除非知道它们的内容不会改变。

public int hashCode() {
    int h = 1;
    int p = position();
    for (int i = limit() - 1; i >= p; i--)
        h = 31 * h + (int)get(i);

    return h;
}

29. public boolean equals(Object ob)

判断这个缓冲区是否等于另一个对象。
当且仅当满足以下条件时,两个字节缓冲区相等:

  1. 它们具有相同的元素类型,
  2. 它们具有相同数量的剩余元素
  3. 两个剩余元素序列(考虑他们的起始位置),是逐点相等的。

字节缓冲区不等于任何其他类型的对象。

public boolean equals(Object ob) {
    if (this == ob)
        return true;
    if (!(ob instanceof ByteBuffer))
        return false;
    ByteBuffer that = (ByteBuffer)ob;
    int thisPos = this.position();
    int thisLim = this.limit();
    int thatPos = that.position();
    int thatLim = that.limit();
    int thisRem = thisLim - thisPos;
    int thatRem = thatLim - thatPos;
    if (thisRem < 0 || thisRem != thatRem)
        return false;
    for (int i = thisLim - 1, j = thatLim - 1; i >= thisPos; i--, j--)
        if (!equals(this.get(i), that.get(j)))
            return false;
    return true;
}

30. private static boolean equals(byte x, byte y)

判断两个字节是否相等。

private static boolean equals(byte x, byte y) {
    return x == y;
}

31. public int compareTo(ByteBuffer that)

将这个缓冲区与另一个缓冲区进行比较。
两个字节缓冲区通过比较它们的剩余元素序列来进行字典顺序比较,而不考虑每个序列在相应缓冲区内的起始位置。两个字节元素被比较,是通过调用Byte.compare(byte, byte)来进行的。
一个字节缓冲区与任何其他类型的对象都不具有可比性。

public int compareTo(ByteBuffer that) {
    int thisPos = this.position();
    int thisRem = this.limit() - thisPos;
    int thatPos = that.position();
    int thatRem = that.limit() - thatPos;
    int length = Math.min(thisRem, thatRem);
    if (length < 0)
        return -1;
    int n = thisPos + Math.min(thisRem, thatRem);
    for (int i = thisPos, j = thatPos; i < n; i++, j++) {
        int cmp = compare(this.get(i), that.get(j));
        if (cmp != 0)
            return cmp;
    }
    return thisRem - thatRem;
}

32. private static int compare(byte x, byte y)

比较两个字节。

private static int compare(byte x, byte y) {
    return Byte.compare(x, y);
}

33. boolean bigEndian = true;

标识是否是大端序。


34. boolean nativeByteOrder = (Bits.byteOrder() == ByteOrder.BIG_ENDIAN);

标识本机的字节序是否是大端序。


35. public final ByteOrder order()

获取当前缓冲区的字节序。
字节序用在读取或写入多字节值时,以及在创建这个字节缓冲区视图的缓冲区时。新创建的字节缓冲区的顺序总是BIG_ENDIAN(大端序)。

public final ByteOrder order() {
    return bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
}

36. public final ByteBuffer order(ByteOrder bo)

修改此缓冲区的字顺序。

public final ByteBuffer order(ByteOrder bo) {
    bigEndian = (bo == ByteOrder.BIG_ENDIAN);
    nativeByteOrder =
        (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
    return this;
}

37. abstract byte _get(int i);

供ByteBufferAs-X-Buffer类使用的get方法。


38. abstract void _put(int i, byte b);

供ByteBufferAs-X-Buffer类使用的put方法。


39. public abstract char getChar();

相对 get 方法,用于读取char类型的值。
读取这个缓冲区当前位置的下两个字节,根据当前字节序将它们组合成一个char类型的值,然后将位置增加 2。


40. public abstract ByteBuffer putChar(char value);

相对 put 方法,用于写入char类型的值(可选操作)。 将给定的char值转换为两个字节,并按照当前字节序写入到这个缓冲区的当前位置,然后将位置增加 2。


41. public abstract char getChar(int index);

绝对 get 方法,用于读取char类型的值。 在给定的索引处读取两个字节,根据当前字节序将它们组合成一个char类型的值。


42. public abstract ByteBuffer putChar(int index, char value);

绝对 put 方法,用于写入char类型的值(可选操作)。 将给定的char值按照当前字节序转换为两个字节,并写入到这个缓冲区的给定索引位置。


43. public abstract CharBuffer asCharBuffer();

创建这个字节缓冲区作为char缓冲区的视图。
新缓冲区的内容将从这个缓冲区的当前位置开始。对这个缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。
新缓冲区的位置将为零,其容量和限制将是这个缓冲区剩余字节数除以二的结果,其标记将未定义。如果这个缓冲区是直接的,新缓冲区也将是直接的,如果这个缓冲区是只读的,新缓冲区也将是只读的。


44. public abstract short getShort();

相对 get 方法,用于读取short类型的值。
读取这个缓冲区当前位置的下两个字节,根据当前字节序将它们组合成一个short类型的值,然后将位置增加 2。


45. public abstract ByteBuffer putShort(short value);

相对 put 方法,用于写入short类型的值(可选操作)。 将给定的short值按照当前字节序转换为两个字节,并写入到这个缓冲区的当前位置,然后将位置增加 2。


46. public abstract short getShort(int index);

绝对 get 方法,用于读取short类型的值。 在给定的索引处读取两个字节,根据当前字节序将它们组合成一个short类型的值。


47. public abstract ByteBuffer putShort(int index, short value);

绝对 put 方法,用于写入short类型的值(可选操作)。 将给定的short值按照当前字节序转换为两个字节,并写入到这个缓冲区的给定索引位置。


48. public abstract ShortBuffer asShortBuffer();

创建这个字节缓冲区作为short缓冲区的视图。
新缓冲区的内容将从这个缓冲区的当前位置开始。对这个缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。
新缓冲区的位置将为零,其容量和限制将是这个缓冲区剩余字节数除以二的结果,其标记将未定义。如果这个缓冲区是直接的,新缓冲区也将是直接的,如果这个缓冲区是只读的,新缓冲区也将是只读的。

49. public abstract int getInt();

相对 get 方法,用于读取int类型的值。 读取这个缓冲区当前位置的下一个四个字节,根据当前字节序将它们组合成一个int类型的值,然后将位置增加 4。


50. public abstract ByteBuffer putInt(int value);

相对 put 方法,用于写入int类型的值(可选操作)。 将给定的int值按照当前字节序转换为四个字节,并写入到这个缓冲区的当前位置,然后将位置增加 4。


51. public abstract int getInt(int index);

绝对 get 方法,用于读取int类型的值。 在给定的索引处读取四个字节,根据当前字节序将它们组合成一个int类型的值。


52. public abstract ByteBuffer putInt(int index, int value);

绝对 put 方法,用于写入int类型的值(可选操作)。 将给定的int值按照当前字节序转换为四个字节,并写入到这个缓冲区的给定索引位置。


53. public abstract IntBuffer asIntBuffer();

创建这个字节缓冲区作为int缓冲区的视图。
新缓冲区的内容将从这个缓冲区的当前位置开始。对这个缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。
新缓冲区的位置将为零,其容量和限制将是这个缓冲区剩余字节数除以四的结果,其标记将未定义。如果这个缓冲区是直接的,新缓冲区也将是直接的,如果这个缓冲区是只读的,新缓冲区也将是只读的。


54. public abstract long getLong();

相对 get 方法,用于读取long类型的值。
读取这个缓冲区当前位置的下八个字节,根据当前字节序将它们组合成一个long类型的值,然后将位置增加 8。


55. public abstract ByteBuffer putLong(long value);

相对 put 方法,用于写入long类型的值(可选操作)。
将给定的long值按照当前字节序转换为八个字节,并写入到这个缓冲区的当前位置,然后将位置增加 8。


56. public abstract long getLong(int index);

绝对 get 方法,用于读取long类型的值。
在给定的索引处读取八个字节,根据当前字节序将它们组合成一个long类型的值。


57. public abstract ByteBuffer putLong(int index, long value);

绝对 put 方法,用于写入long类型的值(可选操作)。
将给定的long值按照当前字节序转换为八个字节,并写入到这个缓冲区的给定索引位置。


58. public abstract LongBuffer asLongBuffer();

创建这个字节缓冲区作为long缓冲区的视图。
新缓冲区的内容将从这个缓冲区的当前位置开始。对这个缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。
新缓冲区的位置将为零,其容量和限制将是这个缓冲区剩余字节数除以八的结果,其标记将未定义。如果这个缓冲区是直接的,新缓冲区也将是直接的,如果这个缓冲区是只读的,新缓冲区也将是只读的。


59. public abstract float getFloat();

相对 get 方法,用于读取float类型的值。
读取这个缓冲区当前位置的下四个字节,根据当前字节序将它们组合成一个float类型的值,然后将位置增加 4。


60. public abstract ByteBuffer putFloat(float value);

相对 put 方法,用于写入float类型的值(可选操作)。
将给定的float值按照当前字节序转换为四个字节,并写入到这个缓冲区的当前位置,然后将位置增加 4。


61. public abstract float getFloat(int index);

绝对 get 方法,用于读取float类型的值。
在给定的索引处读取四个字节,根据当前字节序将它们组合成一个float类型的值。


62. public abstract ByteBuffer putFloat(int index, float value);

绝对 put 方法,用于写入float类型的值(可选操作)。
将给定的float值按照当前字节序转换为四个字节,并写入到这个缓冲区的给定索引位置。


63. public abstract FloatBuffer asFloatBuffer();

创建这个字节缓冲区作为float缓冲区的视图。
新缓冲区的内容将从这个缓冲区的当前位置开始。对这个缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。
新缓冲区的位置将为零,其容量和限制将是这个缓冲区剩余字节数除以四的结果,其标记将未定义。如果这个缓冲区是直接的,新缓冲区也将是直接的,如果这个缓冲区是只读的,新缓冲区也将是只读的。


64. public abstract double getDouble();

相对 get 方法,用于读取double类型的值。
读取这个缓冲区当前位置的下八个字节,根据当前字节序将它们组合成一个double类型的值,然后将位置增加 8。


65. public abstract ByteBuffer putDouble(double value);

相对 put 方法,用于写入double类型的值(可选操作)。
将给定的double值按照当前字节序转换为八个字节,并写入到这个缓冲区的当前位置,然后将位置增加 8。


66. public abstract double getDouble(int index);

绝对 get 方法,用于读取double类型的值。 在给定的索引处读取八个字节,根据当前字节序将它们组合成一个double类型的值。


67. public abstract ByteBuffer putDouble(int index, double value);

绝对 put 方法,用于写入double类型的值(可选操作)。
将给定的double值按照当前字节序转换为八个字节,并写入到这个缓冲区的给定索引位置。


68. public abstract DoubleBuffer asDoubleBuffer();

创建这个字节缓冲区作为double缓冲区的视图。
新缓冲区的内容将从这个缓冲区的当前位置开始。对这个缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。
新缓冲区的位置将为零,其容量和限制将是这个缓冲区剩余字节数除以八的结果,其标记将未定义。如果这个缓冲区是直接的,新缓冲区也将是直接的,如果这个缓冲区是只读的,新缓冲区也将是只读的。