How do I convert byte arrays to hexadecimal and back in Java 17?

When you inspect binary data, a hexadecimal string can be easier to read than a list of decimal byte values. You might use it when troubleshooting a file format or checking a message exchanged between applications.

This tutorial shows a complete conversion in both directions, including readable formatting and invalid input handling.

1. Choose a hexadecimal format

Java 17 introduced java.util.HexFormat as a standard API. No preview or incubator flags are needed.

Use HexFormat.of() for lowercase output without separators. For uppercase output with colons between bytes, use:

HexFormat readable =
        HexFormat.ofDelimiter(":").withUpperCase();

Each byte becomes two hexadecimal digits. These options are documented in the Java 17 HexFormat API.

2. Create the complete example

Save the following as HexFormatExample.java:

import java.util.Arrays;
import java.util.HexFormat;

public class HexFormatExample {
    public static void main(String[] args) {
        byte[] packet = {
                0, 15, 16, 127, (byte) 128, (byte) 255
        };

        HexFormat plain = HexFormat.of();
        HexFormat readable =
                HexFormat.ofDelimiter(":").withUpperCase();

        System.out.println(
                "Compact: " + plain.formatHex(packet));

        String formatted = readable.formatHex(packet);
        System.out.println("Readable: " + formatted);

        byte[] restored = readable.parseHex(formatted);
        System.out.println(
                "Same bytes: " + Arrays.equals(packet, restored));
        System.out.println(
                "Java bytes: " + Arrays.toString(restored));

        try {
            readable.parseHex("00:GG");
        } catch (IllegalArgumentException exception) {
            System.out.println(
                    "Invalid input: expected hexadecimal byte pairs");
        }
    }
}

The program first creates sample data. It then prints two representations, parses the colon-separated version, and checks whether the recovered bytes match the original.

3. Compile and run

Open a terminal in the directory containing the file:

javac --release 17 HexFormatExample.java
java HexFormatExample

Output:

Compact: 000f107f80ff
Readable: 00:0F:10:7F:80:FF
Same bytes: true
Java bytes: [0, 15, 16, 127, -128, -1]
Invalid input: expected hexadecimal byte pairs

4. Understand the result

The two formatted strings represent identical data. Java’s signed byte representation explains the negative decimal values in the recovered array: the bit patterns 80 and FF correspond to -128 and -1.

Arrays.equals() confirms that the conversion preserved the bytes.

Parsing must use the expected delimiters. Invalid digits, such as GG, cause IllegalArgumentException; hexadecimal digit letters themselves are case-insensitive. See HexFormat.parseHex().

Best practices

  • Define the expected representation when exchanging data with another application.
  • Use a matching formatter for encoding and decoding.
  • Keep the original bytes when your next operation requires binary data.
  • Handle invalid external input at the point where it enters your application.
  • Remember that hexadecimal encoding makes data readable; it does not encrypt it.

Summary

Use formatHex() to turn bytes into hexadecimal text and parseHex() to recover them. A short round-trip example helps verify your chosen representation before integrating it into a larger application.

How do I display file contents in hexadecimal?

In this program we read the file contents byte by byte and then print the value in hexadecimal format. As an alternative to read a single byte we can read the file contents into array of bytes at once to process the file faster.

package org.kodejava.io;

import java.io.FileInputStream;

public class HexDumpDemo {
    public static void main(String[] args) throws Exception {
        // Open the file using FileInputStream
        String fileName = "F:/Wayan/Kodejava/kodejava-example/data.txt";
        try (FileInputStream fis = new FileInputStream(fileName)) {
            // A variable to hold a single byte of the file data
            int i = 0;

            // A counter to print a new line every 16 bytes read.
            int count = 0;

            // Read till the end of the file and print the byte in hexadecimal
            // valueS.
            while ((i = fis.read()) != -1) {
                System.out.printf("%02X ", i);
                count++;

                if (count == 16) {
                    System.out.println();
                    count = 0;
                }
            }
        }
    }
}

And here are some result from the file read by the above program.

31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 
35 36 37 38 39 30 0A 

How do I convert decimal to hexadecimal?

To convert decimal number (base 10) to hexadecimal number (base 16) we can use the Integer.toHexString() method. This method takes an integer as parameter and return a string that represent the number in hexadecimal.

To convert back the number from hexadecimal to decimal number we can use the Integer.parseInt() method. This method takes two argument, the number to be converted, which is the string that represent a hexadecimal number. The second argument is the radix, we pass 16 which tell the method if the string is a hexadecimal number.

package org.kodejava.lang;

public class ToHexadecimalExample {
    public static void main(String[] args) {
        // Converting a decimal value to its hexadecimal representation 
        // can be done using Integer.toHexString() method.
        System.out.println(Integer.toHexString(1976));

        // On the other hand to convert hexadecimal string to decimal
        // we can use Integer.parseInt(string, radix) method, 
        // where radix for hexadecimal is 16.
        System.out.println(Integer.parseInt("7b8", 16));
    }
}