HOWTO · Java
How to Convert Byte Array to Integer in Java
This tutorial demonstrates how to convert a byte array to int in Java.
On this page
Converting a byte array to an integer in Java is a common task when dealing with network protocols, file I/O, or binary data formats. The right approach depends on what the bytes represent: sometimes several bytes encode one int, and sometimes each byte is an independent value. This article covers the core Java methods — ByteBuffer, DataInputStream, manual bit shifting, and BigInteger — plus the byte-order and signedness rules that decide whether the result is correct.
Convert Four Bytes to an int with ByteBuffer
ByteBuffer (in java.nio) is the most direct core-Java tool for this conversion. The wrap method creates a buffer that shares the array’s storage, and getInt() reads four bytes starting at the buffer’s current position and interprets them as one int. Run this example:
import java.nio.ByteBuffer;
public class ByteArrayToInt {
public static void main(String[] args) {
byte[] byteArray = {0x00, 0x01, 0x03, 0x10};
int intValue = ByteBuffer.wrap(byteArray).getInt();
System.out.println("Converted Integer Value: " + intValue);
}
}
Output:
Converted Integer Value: 66320
A ByteBuffer is big-endian by default on every platform: the first byte in the array is treated as the most significant byte. If the data was written in little-endian order, select that order explicitly with ByteOrder before reading:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class ByteArrayToIntOrder {
public static void main(String[] args) {
byte[] byteArray = {0x00, 0x01, 0x03, 0x10};
int bigEndianValue = ByteBuffer.wrap(byteArray).getInt();
int littleEndianValue =
ByteBuffer.wrap(byteArray).order(ByteOrder.LITTLE_ENDIAN).getInt();
System.out.println("big-endian: " + bigEndianValue);
System.out.println("little-endian: " + littleEndianValue);
}
}
Output:
big-endian: 66320
little-endian: 268632320
Two details matter here. First, getInt() reads at the buffer’s current position and advances it by four, so calling it twice on the same buffer reads the next four bytes; a fresh wrap always starts at position 0. Second, when fewer than four bytes remain, getInt() throws a BufferUnderflowException, so check the input length before reading.
Read Four Bytes with DataInputStream
When the bytes arrive through a stream — or when you want to read several primitive values in sequence — DataInputStream is a good fit. Wrap the array in a ByteArrayInputStream, wrap that in a DataInputStream, and call readInt():
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
public class ByteArrayToIntWithDataInputStream {
public static void main(String[] args) throws IOException {
byte[] byteArray = {0x00, 0x01, 0x03, 0x10};
try (DataInputStream input =
new DataInputStream(new ByteArrayInputStream(byteArray))) {
int intValue = input.readInt();
System.out.println("Converted Integer Value: " + intValue);
}
}
}
Output:
Converted Integer Value: 66320
readInt() always interprets the next four bytes in big-endian order, regardless of the platform. When fewer than four bytes remain in the stream, it throws an EOFException, which you can catch to report a short input instead of crashing:
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
public class ByteArrayToIntShortInput {
public static void main(String[] args) throws IOException {
byte[] byteArray = {0x03, 0x10};
try (DataInputStream input =
new DataInputStream(new ByteArrayInputStream(byteArray))) {
int intValue = input.readInt();
System.out.println("Converted Integer Value: " + intValue);
} catch (EOFException e) {
System.out.println("readInt() needs four bytes, but only " + byteArray.length + " remain");
}
}
}
Output:
readInt() needs four bytes, but only 2 remain
Build an int by Shifting Bytes
Shifting the bytes yourself shows exactly how the conversion works and gives full control over order and length. For each byte, shift the accumulated value left by 8 bits and OR in the next byte:
public class ByteArrayToIntManually {
public static void main(String[] args) {
byte[] byteArray = {0x00, 0x01, 0x03, 0x10};
int intValue = 0;
for (byte b : byteArray) {
intValue = (intValue << 8) | (b & 0xFF);
}
System.out.println("Converted Integer Value: " + intValue);
}
}
Output:
Converted Integer Value: 66320
The mask b & 0xFF is required because the Java byte type is signed: 0x80 is stored as -128. Without the mask, | would combine 0xFFFFFF80 instead of 0x00000080, corrupting every higher byte. This loop assembles the bytes in big-endian order — the first array element is the most significant byte — and assumes the array holds exactly four bytes. For a different order, iterate the array in the opposite direction; for more bytes, accumulate into a long instead of an int.
Interpret a Byte Array with BigInteger
BigInteger accepts a byte array directly in its constructor and interprets it as a signed, big-endian, two’s-complement number of arbitrary length. intValue() then narrows the result to an int:
import java.math.BigInteger;
public class ByteArrayToIntWithBigInteger {
public static void main(String[] args) {
byte[] byteArray = {0x00, 0x01, 0x03, 0x10};
int intValue = new BigInteger(byteArray).intValue();
System.out.println("Converted Integer Value: " + intValue);
}
}
Output:
Converted Integer Value: 66320
Because the interpretation is signed, a leading 1 bit produces a value below 0; pass a signum of 1 as the first constructor argument for the unsigned interpretation. Keep in mind that intValue() keeps only the low 32 bits — it silently truncates values that do not fit in an int:
import java.math.BigInteger;
public class BigIntegerSignAndRange {
public static void main(String[] args) {
byte[] allOnes = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
System.out.println("signed: " + new BigInteger(allOnes));
System.out.println("unsigned: " + new BigInteger(1, allOnes));
System.out.println("narrowed to int: " + new BigInteger(1, allOnes).intValue());
}
}
Output:
signed: -1
unsigned: 4294967295
narrowed to int: -1
BigInteger is the natural choice when the array is longer than four bytes or when you need the unsigned magnitude before narrowing.
Convert Each Byte Separately
All methods above combine several bytes into one number. If each byte is an independent value — sensor readings, color channels, protocol fields — convert the elements individually instead. Note the distinction: getShort() or readShort() on two bytes produces one combined short, it does not convert each byte separately.
Also remember that the Java byte type is signed, ranging from -128 to 127. When the intent is an unsigned value from 0 to 255, use Byte.toUnsignedInt (available since Java 8) or the equivalent b & 0xFF mask:
public class PrintEachByte {
public static void main(String[] args) {
byte[] byteArray = {0x03, 0x04, (byte) 0x80, (byte) 0xFF};
for (byte b : byteArray) {
System.out.println("signed: " + b + " unsigned: " + Byte.toUnsignedInt(b));
}
}
}
Output:
signed: 3 unsigned: 3
signed: 4 unsigned: 4
signed: -128 unsigned: 128
signed: -1 unsigned: 255
Choose a Method and Handle Edge Cases
Each approach fits a different situation:
ByteBufferis the first choice for reading a four-byteintfrom an array: it is compact, supports both byte orders throughByteOrder, and providesgetLong(),getShort(), and friends for other widths.DataInputStreamsuits code that already works with streams and needs to read several typed values in sequence; its reads are always big-endian.- Manual shifting costs a few more lines but controls order, offset, and width precisely and needs no buffer or stream object.
BigIntegerhandles arrays longer than four bytes and explicit signed or unsigned interpretation before narrowing.- Per-byte conversion with
Byte.toUnsignedIntapplies when every element is its own value rather than part of one number.
Whichever method you choose, check these points before converting:
- Input length: a four-byte read on a shorter array fails —
BufferUnderflowExceptionforByteBuffer,EOFExceptionforDataInputStream, and anArrayIndexOutOfBoundsExceptionor silently wrong result for manual code. - Byte order: the reader’s order must match the order the bytes were written in;
ByteBufferdefaults to big-endian and can be switched withByteOrder, whileDataInputStreamreads are always big-endian with no order option. - Signedness and range:
getInt()andreadInt()return a signedint, so an unsigned 32-bit value aboveInteger.MAX_VALUEappears below 0. UseInteger.toUnsignedLong(intValue)or accumulate into alongwhen the source data is unsigned. - Buffer position: reusing a
ByteBuffercontinues from its current position, not from the start; callrewind()orwrapagain to reread the array.