How do I initialize a byte array in Java?

790,697

Solution 1

You can use an utility function to convert from the familiar hexa string to a byte[]. When used to define a final static constant, the performance cost is irrelevant.

Since Java 17

There's now java.util.HexFormat which lets you do

byte[] CDRIVES = HexFormat.of().parseHex("e04fd020ea3a6910a2d808002b30309d");

This utility class lets you specify a format which is handy if you find other formats easier to read or when you're copy-pasting from a reference source:

byte[] CDRIVES = HexFormat.ofDelimiter(":")
    .parseHex("e0:4f:d0:20:ea:3a:69:10:a2:d8:08:00:2b:30:30:9d");

Before Java 17

I'd suggest you use the function defined by Dave L in Convert a string representation of a hex dump to a byte array using Java?

byte[] CDRIVES = hexStringToByteArray("e04fd020ea3a6910a2d808002b30309d");

I insert it here for maximum readability :

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

Solution 2

byte[] myvar = "Any String you want".getBytes();

String literals can be escaped to provide any character:

byte[] CDRIVES = "\u00e0\u004f\u00d0\u0020\u00ea\u003a\u0069\u0010\u00a2\u00d8\u0008\u0000\u002b\u0030\u0030\u009d".getBytes();

Solution 3

In Java 6, there is a method doing exactly what you want:

private static final byte[] CDRIVES = javax.xml.bind.DatatypeConverter.parseHexBinary("e04fd020ea3a6910a2d808002b30309d")

Alternatively you could use Google Guava:

import com.google.common.io.BaseEncoding;
private static final byte[] CDRIVES = BaseEncoding.base16().lowerCase().decode("E04FD020ea3a6910a2d808002b30309d".toLowerCase());

The Guava method is overkill, when you are using small arrays. But Guava has also versions that can parse input streams. This is a nice feature when dealing with big hexadecimal inputs.

Solution 4

You can use the Java UUID class to store these values, instead of byte arrays:

UUID

public UUID(long mostSigBits,
            long leastSigBits)

Constructs a new UUID using the specified data. mostSigBits is used for the most significant 64 bits of the UUID and leastSigBits becomes the least significant 64 bits of the UUID.

Solution 5

Smallest internal type, which at compile time can be assigned by unsigned hex numbers is char, as

private static final char[] CDRIVES_char = new char[] {0xe0, 0xf4, ...};

In order to have an equivalent byte array one might deploy conversions as

public static byte[] charToByteArray(char[] x)
{
    final byte[] res = new byte[x.length];
    for (int i = 0; i < x.length; i++)
    {
        res[i] = (byte) x[i];
    }
    return res;
}

public static byte[][] charToByteArray(char[][] x)
{
    final byte[][] res = new byte[x.length][];
    for (int i = 0; i < x.length; i++)
    {
        res[i] = charToByteArray(x[i]);
    }
    return res;
}
Share:
790,697

Related videos on Youtube

dfickling
Author by

dfickling

Updated on July 29, 2022

Comments

  • dfickling
    dfickling almost 2 years

    I have to store some constant values (UUIDs) in byte array form in java, and I'm wondering what the best way to initialize those static arrays would be. This is how I'm currently doing it, but I feel like there must be a better way.

    private static final byte[] CDRIVES = new byte[] { (byte)0xe0, 0x4f, (byte)0xd0,
        0x20, (byte)0xea, 0x3a, 0x69, 0x10, (byte)0xa2, (byte)0xd8, 0x08, 0x00, 0x2b,
        0x30, 0x30, (byte)0x9d };
    private static final byte[] CMYDOCS = new byte[] { (byte)0xba, (byte)0x8a, 0x0d,
        0x45, 0x25, (byte)0xad, (byte)0xd0, 0x11, (byte)0x98, (byte)0xa8, 0x08, 0x00,
        0x36, 0x1b, 0x11, 0x03 };
    private static final byte[] IEFRAME = new byte[] { (byte)0x80, 0x53, 0x1c,
        (byte)0x87, (byte)0xa0, 0x42, 0x69, 0x10, (byte)0xa2, (byte)0xea, 0x08,
        0x00, 0x2b, 0x30, 0x30, (byte)0x9d };
    ...
    and so on
    

    Is there anything I could use that may be less efficient, but would look cleaner? for example:

    private static final byte[] CDRIVES =
        new byte[] { "0xe04fd020ea3a6910a2d808002b30309d" };
    
    • Martin Zeitler
      Martin Zeitler over 3 years
      Since they're declared as static final, this might already be the most proper way; the accepted answer completely ignores these keywords and would not even work with them.
  • jww
    jww almost 10 years
    Doesn't that turn the string "0000" to {0x30,0x30,0x30,0x30} (ASCII) rather than {0x00,0x00,0x00,0x00} (binary) as desired by the poster?
  • Peter DeGlopper
    Peter DeGlopper almost 9 years
    The Guava example doesn't quite work as written - it needs to be base16().lowerCase().decode(...) if you have lower case hex digits. docs.guava-libraries.googlecode.com/git/javadoc/com/google/…
  • stefan.schwetschke
    stefan.schwetschke almost 9 years
    @PeterDeGlopper Good finding, I've updated the answer so the code now handles strings with both lower and upper case characters.
  • e18r
    e18r almost 6 years
    Look at the question's title. Then look back at this answer. Now tell me, what's wrong about it? It might not solve the poster's particular issue, but it sure solved mine. I needed to transform a string into a byte array to use as a seed for a pseudorandom number generator and this worked like a charm.
  • randomdude999
    randomdude999 over 5 years
    javax.xml.bind was sadly removed in Java 9.
  • quant
    quant over 5 years
    @e18r It is generating bytes, yes, but you don't know which since this depence on the default charset. At least use .getBytes(desiredEncoding).
  • Robert Achmann
    Robert Achmann over 5 years
    @petmez dumb question: in JAVA, is something like "".getBytes(UTF_8)); (getBytes on an empty string) a safe thing to do? is it 'legal'? Or can I just do: = new byte[0]; ?
  • Jazzepi
    Jazzepi about 4 years
    @RobertAchmann "".getbytes("UTF-8") should return an empty array and is perfectly legal.
  • Dave L.
    Dave L. over 2 years
    In Java 17, you can now use java.util.HexFormat.of().parseHex("e04fd020ea3a6910a2d808002‌​b30309d")
  • Denys Séguret
    Denys Séguret over 2 years
    @DaveL. Thanks. Updating the answer
  • Sam Ginrich
    Sam Ginrich about 2 years
    Think you mean ´bObj.write(int value)´ which actual writes a byte and accepts ´unsigned´ byte-values as well.