- 已知子类:
ByteBuffer
,CharBuffer
,DoubleBuffer
,FloatBuffer
,IntBuffer
,LongBuffer
,ShortBuffer
缓冲区是特定原始类型元素的线性有限序列。除了它的内容之外,缓冲区的基本属性是它的容量、限制和位置:
缓冲区的capacity是它包含的元素的数量。缓冲区的容量永远不会为负,也永远不会改变。
缓冲区的limit是不应读取或写入的第一个元素的索引。缓冲区的限制永远不会是负数,也永远不会大于它的容量。
缓冲区的position是要读取或写入的下一个元素的索引。缓冲区的位置永远不会为负,也永远不会大于其限制。
每个非布尔原始类型都有此类的一个子类。
传输数据
这个类的每个子类定义了两个类别get和put操作:
相对的操作从当前位置开始读取或写入一个或多个元素,然后按传输的元素数增加位置。如果请求的转账超过限额,则亲属get操作抛出一个
BufferUnderflowException
和一个亲戚put操作抛出一个BufferOverflowException
;在任何一种情况下,都不会传输任何数据。绝对操作采用显式元素索引并且不影响位置。绝对get和put如果索引参数超过限制,操作将抛出
IndexOutOfBoundsException
。
当然,也可以通过适当通道的 I/O 操作将数据传入或传出缓冲区,这些操作始终与当前位置相关。
标记和重置
缓冲区的mark是调用 reset
方法时其位置将重置到的索引。标记并不总是被定义,但当它被定义时,它永远不会是负的,也永远不会大于位置。如果标记已定义,则当位置或限制调整为小于标记的值时,它将被丢弃。如果未定义标记,则调用 reset
方法会导致抛出 InvalidMarkException
。
不变量
以下不变量适用于标记、位置、限制和容量值:
0
<=
mark<=
position<=
limit<=
capacity
新创建的缓冲区始终具有零位置和未定义的标记。初始限制可以是零,也可以是其他值,具体取决于缓冲区的类型及其构造方式。新分配的缓冲区的每个元素都初始化为零。
附加操作
除了访问位置、限制和容量值以及标记和重置的方法之外,此类还定义了以下对缓冲区的操作:
clear()
为新的通道读取或相关序列准备好缓冲区put操作:它将容量限制和位置设置为零。flip()
为新的通道写入或相关序列准备好缓冲区get操作:它将限制设置为当前位置,然后将位置设置为零。rewind()
使缓冲区准备好重新读取它已经包含的数据:它保持限制不变并将位置设置为零。slice()
和slice(index,length)
方法创建缓冲区的子序列:它们保持限制和位置不变。duplicate()
创建缓冲区的浅表副本:它保留限制和位置不变。
只读缓冲区
每个缓冲区都是可读的,但不是每个缓冲区都是可写的。每个缓冲区类的变异方法指定为可选操作在只读缓冲区上调用时将抛出 ReadOnlyBufferException
。只读缓冲区不允许更改其内容,但其标记、位置和限制值是可变的。缓冲区是否是只读的可以通过调用它的isReadOnly
方法来确定。
线程安全
多个并发线程使用缓冲区是不安全的。如果一个缓冲区要被多个线程使用,那么对缓冲区的访问应该通过适当的同步来控制。
调用链接
此类中没有返回值的方法被指定为返回调用它们的缓冲区。这允许链接方法调用;例如,语句序列
可以用单个更紧凑的语句代替b.flip(); b.position(23); b.limit(42);
b.flip().position(23).limit(42);
-
方法总结
修饰符和类型方法描述abstract Object
array()
返回支持此缓冲区的数组(可选操作).abstract int
返回缓冲区第一个元素在此缓冲区的后备数组中的偏移量(可选操作).final int
capacity()
返回此缓冲区的容量。clear()
清除此缓冲区。abstract Buffer
创建一个共享此缓冲区内容的新缓冲区。flip()
翻转此缓冲区。abstract boolean
hasArray()
告知此缓冲区是否由可访问数组支持。final boolean
告诉当前位置和限制之间是否有任何元素。abstract boolean
isDirect()
判断此缓冲区是否为 直接的 。abstract boolean
告知此缓冲区是否为只读。final int
limit()
返回此缓冲区的限制。limit
(int newLimit) 设置此缓冲区的限制。mark()
在其位置设置此缓冲区的标记。final int
position()
返回此缓冲区的位置。position
(int newPosition) 设置此缓冲区的位置。final int
返回当前位置和限制之间的元素数。reset()
将此缓冲区的位置重置为先前标记的位置。rewind()
倒带此缓冲区。abstract Buffer
slice()
创建一个新缓冲区,其内容是此缓冲区内容的共享子序列。abstract Buffer
slice
(int index, int length) 创建一个新缓冲区,其内容是此缓冲区内容的共享子序列。
-
方法详情
-
capacity
public final int capacity()返回此缓冲区的容量。- 返回:
- 这个缓冲区的容量
-
position
public final int position()返回此缓冲区的位置。- 返回:
- 这个缓冲区的位置
-
position
设置此缓冲区的位置。如果标记已定义且大于新位置,则将其丢弃。- 参数:
newPosition
- 新的位置值;必须为非负且不大于电流限制- 返回:
- 这个缓冲区
- 抛出:
IllegalArgumentException
- 如果newPosition
的先决条件不成立
-
limit
public final int limit()返回此缓冲区的限制。- 返回:
- 这个缓冲区的限制
-
limit
设置此缓冲区的限制。如果位置大于新限制,则将其设置为新限制。如果标记已定义且大于新限制,则将其丢弃。- 参数:
newLimit
- 新的极限值;必须为非负且不大于此缓冲区的容量- 返回:
- 这个缓冲区
- 抛出:
IllegalArgumentException
- 如果newLimit
的先决条件不成立
-
mark
在其位置设置此缓冲区的标记。- 返回:
- 这个缓冲区
-
reset
将此缓冲区的位置重置为先前标记的位置。调用此方法既不会更改也不会丢弃标记的值。
- 返回:
- 这个缓冲区
- 抛出:
InvalidMarkException
- 如果未设置标记
-
clear
清除此缓冲区。位置设置为零,限制设置为容量,标记被丢弃。在使用一系列通道读取或之前调用此方法put填充此缓冲区的操作。例如:
buf.clear(); // Prepare buffer for reading in.read(buf); // Read data
这种方法实际上并没有擦除缓冲区中的数据,但它的命名就好像它确实擦除一样,因为它最常用于可能是这种情况的情况。
- 返回:
- 这个缓冲区
-
flip
翻转此缓冲区。限制设置为当前位置,然后位置设置为零。如果标记已定义,则将其丢弃。经过一系列通道读取或put操作,调用此方法来准备一系列通道写入或相关get操作。例如:
buf.put(magic); // Prepend header in.read(buf); // Read data into rest of buffer buf.flip(); // Flip buffer out.write(buf); // Write header + data to channel
在将数据从一个地方传输到另一个地方时,该方法通常与
compact
方法结合使用。- 返回:
- 这个缓冲区
-
rewind
倒带此缓冲区。位置设置为零,标记被丢弃。在一系列通道写入或之前调用此方法get操作,假设已经适当地设置了限制。例如:
out.write(buf); // Write remaining data buf.rewind(); // Rewind buffer buf.get(array); // Copy data into array
- 返回:
- 这个缓冲区
-
remaining
public final int remaining()返回当前位置和限制之间的元素数。- 返回:
- 此缓冲区中剩余的元素数
-
hasRemaining
public final boolean hasRemaining()告诉当前位置和限制之间是否有任何元素。- 返回:
true
当且仅当此缓冲区中至少有一个元素剩余
-
isReadOnly
public abstract boolean isReadOnly()告知此缓冲区是否为只读。- 返回:
true
当且仅当此缓冲区是只读的
-
hasArray
public abstract boolean hasArray()告知此缓冲区是否由可访问数组支持。如果此方法返回
true
,则可以安全地调用array
和arrayOffset
方法。- 返回:
true
当且仅当此缓冲区由数组支持并且不是只读的- 自从:
- 1.6
-
array
返回支持此缓冲区的数组(可选操作).此方法旨在允许将支持数组的缓冲区更有效地传递给本机代码。具体的子类为此方法提供更强类型的返回值。
对此缓冲区内容的修改将导致返回数组的内容被修改,反之亦然。
在调用此方法之前调用
hasArray
方法,以确保此缓冲区具有可访问的后备数组。- 返回:
- 支持此缓冲区的数组
- 抛出:
ReadOnlyBufferException
- 如果此缓冲区由数组支持但为只读UnsupportedOperationException
- 如果此缓冲区不受可访问数组的支持- 自从:
- 1.6
-
arrayOffset
public abstract int arrayOffset()返回缓冲区第一个元素在此缓冲区的后备数组中的偏移量(可选操作).如果此缓冲区由数组支持,则缓冲区位置p对应数组索引p
arrayOffset()
。在调用此方法之前调用
hasArray
方法,以确保此缓冲区具有可访问的后备数组。- 返回:
- 缓冲区第一个元素在此缓冲区数组中的偏移量
- 抛出:
ReadOnlyBufferException
- 如果此缓冲区由数组支持但为只读UnsupportedOperationException
- 如果此缓冲区不受可访问数组的支持- 自从:
- 1.6
-
isDirect
public abstract boolean isDirect()判断此缓冲区是否为 直接的 。- 返回:
true
当且仅当此缓冲区是直接的- 自从:
- 1.6
-
slice
创建一个新缓冲区,其内容是此缓冲区内容的共享子序列。新缓冲区的内容将从该缓冲区的当前位置开始。对此缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。
新缓冲区的位置将为零,其容量和限制将为该缓冲区中剩余的元素数,其标记将未定义。当且仅当此缓冲区是直接的时,新缓冲区将是直接的,并且当且仅当此缓冲区是只读的时,它将是只读的。
- 返回:
- 新缓冲区
- 自从:
- 9
-
slice
创建一个新缓冲区,其内容是此缓冲区内容的共享子序列。新缓冲区的内容将从该缓冲区中的位置
index
开始,并将包含length
个元素。对此缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。新缓冲区的位置将为零,其容量和限制将为
length
,其标记将未定义。当且仅当此缓冲区是直接的时,新缓冲区将是直接的,并且当且仅当此缓冲区是只读的时,它将是只读的。- 参数:
index
- 该缓冲区中新缓冲区内容开始的位置;必须为非负且不大于limit()
length
- 新缓冲区将包含的元素数;必须为非负且不大于limit() - index
- 返回:
- 新缓冲区
- 抛出:
IndexOutOfBoundsException
- 如果index
为负或大于limit()
,则length
为负,或length > limit() - index
- 自从:
- 13
-
duplicate
创建一个共享此缓冲区内容的新缓冲区。新缓冲区的内容将是该缓冲区的内容。对此缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置、限制和标记值将是独立的。
新缓冲区的容量、限制、位置和标记值将与该缓冲区的相同。当且仅当此缓冲区是直接的时,新缓冲区将是直接的,并且当且仅当此缓冲区是只读的时,它将是只读的。
- 返回:
- 新缓冲区
- 自从:
- 9
-