Java Reference
In-Depth Information
IntBuffer
or a
ByteBuffer
or a
CharBuffer
or something else. You write code to one
of these subclasses, not to the common
Buffer
superclass.
Each typed buffer class has several factory methods that create implementation-specific
subclasses of that type in various ways. Empty buffers are normally created by
allocate
methods. Buffers that are prefilled with data are created by
wrap
methods. The allocate
methods are often useful for input, and the wrap methods are normally used for output.
Allocation
The basic
allocate()
method simply returns a new, empty buffer with a specified fixed
capacity. For example, these lines create byte and int buffers, each with a size of 100:
ByteBuffer
buffer1
=
ByteBuffer
.
allocate
(
100
);
IntBuffer
buffer2
=
IntBuffer
.
allocate
(
100
);
The cursor is positioned at the beginning of the buffer (i.e., the position is 0). A buffer
created by
allocate()
will be implemented on top of a Java array, which can be accessed
by the
array()
and
arrayOffset()
methods. For example, you could read a large chunk
of data into a buffer using a channel and then retrieve the array from the buffer to pass
to other methods:
byte
[]
data1
=
buffer1
.
array
();
int
[]
data2
=
buffer2
.
array
();
The
array()
method does expose the buffer's private data, so use it with caution.
Changes to the backing array are reflected in the buffer and vice versa. The normal
pattern here is to fill the buffer with data, retrieve its backing array, and then operate on
the array. This isn't a problem as long as you don't write to the buffer after you've started
working with the array.
Direct allocation
The
ByteBuffer
class (but not the other buffer classes) has an additional
allocateDir
ect()
method that may not create a backing array for the buffer. The VM may impleā
ment a directly allocated
ByteBuffer
using direct memory access to the buffer on an
Ethernet card, kernel memory, or something else. It's not required, but it's allowed, and
this can improve performance for I/O operations. From an API perspective,
allocate
Direct()
is used exactly like
allocate()
:
ByteBuffer
buffer
=
ByteBuffer
.
allocateDirect
(
100
);
Invoking
array()
and
arrayOffset()
on a direct buffer will throw an
UnsupportedO
perationException
. Direct buffers may be faster on some virtual machines, especially
if the buffer is large (roughly a megabyte or more). However, direct buffers are more
expensive to create than indirect buffers, so they should only be allocated when the
buffer is expected to be around for a while. The details are highly VM dependent. As is
generally true for most performance advice, you probably shouldn't even consider using
direct buffers until measurements prove performance is an issue.