Fundamentals 11 min read

Mastering Java NIO Buffers: Creation, Core Properties, and Operations

This article explains Java NIO buffers, covering how to create them, their four core properties (mark, position, limit, capacity), essential methods like allocate, allocateDirect, flip, rewind, clear, and demonstrates usage with comprehensive code examples and diagrams.

Java Interview Crash Guide
Java Interview Crash Guide
Java Interview Crash Guide
Mastering Java NIO Buffers: Creation, Core Properties, and Operations

Introduction

Buffers are containers for primitive types defined in java.nio. All buffers extend the abstract Buffer class and are used to interact with NIO channels, where data is written to a buffer from a channel and read back.

Java NIO buffers are mainly used for channel interaction.

1. Creating Buffers

Buffers are essentially arrays that store data of various types (except boolean). For each type there is a specific buffer class such as ByteBuffer, IntBuffer, etc. Buffers are created by calling allocate() with the desired capacity.

// Create a 1 KB buffer
ByteBuffer buf = ByteBuffer.allocate(1024);

Usually allocate() is used, but for high‑performance scenarios allocateDirect() may be preferred. allocate() creates a non‑direct buffer, while allocateDirect() creates a direct buffer.

2. Four Core Buffer Properties

The underlying array for a ByteBuffer is a byte[]. The Buffer class defines four core integer fields:

private int mark = -1;
private int position = 0;
private int limit;
private int capacity;

These fields act like abstract pointers. Their relationship is:

0 <= mark <= position <= limit <= capacity

position : index of the next element to be read or written.

mark : a saved position set by mark(), which can be restored with reset().

limit : the first element that should not be read or written.

capacity : the total size of the buffer; it cannot be changed after allocation.

2.1 Initial Pointer State

For a buffer with capacity 5:

ByteBuffer buf = ByteBuffer.allocate(5);

2.2 State After Data Is Written

In write mode, limit and position differ.

// write mode
byteBuffer.put("Tom".getBytes());

In read mode:

// read mode
byteBuffer.get();

3. Core Buffer Methods

3.1 Data Access

Data is stored with put() and retrieved with get(). A flip operation is required between writing and reading.

put() puts data into the buffer; get() retrieves data.

3.2 flip(), rewind(), clear()

flip(): switches buffer from writing to reading.

rewind(): resets position (and optionally limit) to the beginning of the current mode.

clear(): resets position to 0 and limit to capacity, discarding the mark; the data remains but is considered forgotten.

3.3 mark() and reset()

mark() records the current position; reset() returns to that mark.

3.4 hasRemaining() and remaining()

hasRemaining() checks if there are unread elements.

remaining() returns the number of elements that can still be accessed (limit‑position).

3.5 Example Program

The following program demonstrates buffer creation, writing, flipping, reading, rewinding, clearing, and using mark/reset.

// allocate 1 KB buffer
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
System.out.println("=============allocate()===========");
System.out.println("position = " + byteBuffer.position());
System.out.println("limit = " + byteBuffer.limit());
System.out.println("capacity = " + byteBuffer.capacity());

// put data
System.out.println("=============put()===========" );
String name = "abcde";
byteBuffer.put(name.getBytes());
System.out.println("position = " + byteBuffer.position());
System.out.println("limit = " + byteBuffer.limit());
System.out.println("capacity = " + byteBuffer.capacity());

// flip
System.out.println("============flip()===========" );
byteBuffer.flip();
System.out.println("position = " + byteBuffer.position());
System.out.println("limit = " + byteBuffer.limit());
System.out.println("capacity = " + byteBuffer.capacity());

// get data
System.out.println("============get()===========" );
byte[] dst = new byte[byteBuffer.limit()];
byteBuffer.get(dst);
System.out.println("position = " + byteBuffer.position());
System.out.println("limit = " + byteBuffer.limit());
System.out.println("capacity = " + byteBuffer.capacity());
System.out.println(new String(dst));

// rewind
System.out.println("============rewind()===========" );
byteBuffer.rewind();
System.out.println("position = " + byteBuffer.position());
System.out.println("limit = " + byteBuffer.limit());
System.out.println("capacity = " + byteBuffer.capacity());

// clear
System.out.println("============clear()===========" );
byteBuffer.clear();
System.out.println("position = " + byteBuffer.position());
System.out.println("limit = " + byteBuffer.limit());
System.out.println("capacity = " + byteBuffer.capacity());

// mark and reset example
ByteBuffer buf = ByteBuffer.allocate(5);
buf.put("abcde".getBytes());
buf.flip();
byte[] dst2 = new byte[buf.limit()];
buf.get(dst2, 0, 2);
System.out.println("First read: " + new String(dst2));
System.out.println("position: " + buf.position());
buf.mark();
buf.get(dst2, 2, 2);
System.out.println("Second read: " + new String(dst2));
System.out.println("position: " + buf.position());
buf.reset();
System.out.println("reset to mark");
System.out.println("position: " + buf.position());

4. Direct vs. Non‑Direct Buffers

Byte buffers can be either direct or non‑direct. Non‑direct buffers are allocated on the JVM heap and involve copying data between kernel and user space. Direct buffers are allocated outside the heap, avoiding the copy and improving performance, but they are not managed by the garbage collector and are expensive to allocate and destroy.

Only byte buffers support the isDirect() check.

Note: Direct buffers give better performance but should be used only when necessary because they are harder to control and have higher allocation costs.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaperformancenioiobufferByteBuffer
Java Interview Crash Guide
Written by

Java Interview Crash Guide

Dedicated to sharing Java interview Q&A; follow and reply "java" to receive a free premium Java interview guide.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.