杰瑞科技汇

Java 16进制byte数组如何互转?

核心概念

  • Byte (字节): 在 Java 中,byte 是一个 8 位有符号整数,其范围是 -128127
  • 16 进制 (Hexadecimal): 一种基数为 16 的数制系统,使用数字 0-9 和字母 a-f (或 A-F) 来表示数值,一个 16 进制字符(如 A)代表 4 个二进制位(即半字节,nibble),由于一个字节是 8 位,所以它恰好可以用两个 16 进制字符来表示。
    • 十进制 10 -> 二进制 00001010 -> 16 进制 0x0A0A
    • 十进制 -128 -> 二进制 10000000 -> 16 进制 0x80

将 byte 数组转换为 16 进制字符串

这是最常见的操作,byte 数组中的每个字节都需要被转换成两个 16 进制字符。

Java 16进制byte数组如何互转?-图1
(图片来源网络,侵删)

方法 1:使用 javax.xml.bind.DatatypeConverter (最简单,但已过时)

这个方法非常直观,代码量少,但在 Java 9 中,javax.xml.bind 包被移到了 Java EE 模块中,需要额外引入依赖,因此在新项目中不推荐使用。

import javax.xml.bind.DatatypeConverter;
public class BytesToHexConverter {
    public static void main(String[] args) {
        byte[] bytes = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) -0x12 }; // -0x12 等于 0xEE
        // 使用 DatatypeConverter 进行转换
        String hexString = DatatypeConverter.printHexBinary(bytes);
        System.out.println("原始 byte 数组: " + java.util.Arrays.toString(bytes));
        System.out.println("16 进制字符串: " + hexString); // 输出: 12345678EE
    }
}

方法 2:使用 Apache Commons Codec (推荐,工业级标准)

这是目前最推荐、最常用、最稳定的方法,你需要先添加 Maven 或 Gradle 依赖。

Maven 依赖:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version> <!-- 使用最新版本 -->
</dependency>

代码示例:

Java 16进制byte数组如何互转?-图2
(图片来源网络,侵删)
import org.apache.commons.codec.binary.Hex;
public class BytesToHexApache {
    public static void main(String[] args) {
        byte[] bytes = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) -0x12 };
        // 使用 Apache Commons Codec 进行转换
        String hexString = Hex.encodeHexString(bytes);
        System.out.println("原始 byte 数组: " + java.util.Arrays.toString(bytes));
        System.out.println("16 进制字符串: " + hexString); // 输出: 12345678ee
    }
}

方法 3:手动实现 (无需依赖,适合学习或简单场景)

如果你不想引入任何外部库,可以自己实现,核心思路是:

  1. 遍历 byte 数组。
  2. 对每个字节,使用 & 0xFF 将其转换为无符号整数(0-255),避免负数问题。
  3. 使用 Integer.toHexString() 将这个整数转换为 16 进制字符串。
  4. 判断转换后的字符串长度,如果只有 1 位(如 a),则在前面补一个 0
  5. 将所有字符拼接起来。
public class BytesToHexManual {
    public static String bytesToHex(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            // & 0xFF 确保将 byte 转换为无符号的 int 值 (0-255)
            String hex = Integer.toHexString(b & 0xFF);
            // 如果转换后的字符只有一位,前面补0
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
    public static void main(String[] args) {
        byte[] bytes = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) -0x12 };
        String hexString = bytesToHex(bytes);
        System.out.println("原始 byte 数组: " + java.util.Arrays.toString(bytes));
        System.out.println("16 进制字符串: " + hexString); // 输出: 12345678ee
    }
}

将 16 进制字符串转换为 byte 数组

这是上述操作的逆过程,将 16 进制字符串每两个字符解析为一个字节。

方法 1:使用 javax.xml.bind.DatatypeConverter (最简单,但已过时)

import javax.xml.bind.DatatypeConverter;
public class HexToBytesConverter {
    public static void main(String[] args) {
        String hexString = "12345678ee";
        // 使用 DatatypeConverter 进行转换
        byte[] bytes = DatatypeConverter.parseHexBinary(hexString);
        System.out.println("16 进制字符串: " + hexString);
        System.out.println("转换后的 byte 数组: " + java.util.Arrays.toString(bytes)); // 输出: [18, 52, 86, 120, -18]
    }
}

方法 2:使用 Apache Commons Codec (推荐)

import org.apache.commons.codec.binary.Hex;
public class HexToBytesApache {
    public static void main(String[] args) {
        String hexString = "12345678ee";
        // 使用 Apache Commons Codec 进行转换
        byte[] bytes = Hex.decodeHex(hexString.toCharArray());
        System.out.println("16 进制字符串: " + hexString);
        System.out.println("转换后的 byte 数组: " + java.util.Arrays.toString(bytes)); // 输出: [18, 52, 86, 120, -18]
    }
}

方法 3:手动实现 (无需依赖,适合学习或简单场景)

  1. 检查 16 进制字符串的长度,如果不是偶数,则无法转换。
  2. 从头开始,每两个字符作为一个单元。
  3. 使用 Integer.parseInt(substring, 16) 将这两个字符解析为一个整数。
  4. 将这个整数强制转换为 byte 类型。
public class HexToBytesManual {
    public static byte[] hexToBytes(String hexString) {
        if (hexString == null || hexString.length() % 2 != 0) {
            throw new IllegalArgumentException("16 进制字符串必须为非空且长度为偶数");
        }
        byte[] bytes = new byte[hexString.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            // 从 i*2 位置开始取两个字符
            String hex = hexString.substring(2 * i, 2 * i + 2);
            // 将 16 进制字符串转换为整数,再强制转换为 byte
            bytes[i] = (byte) Integer.parseInt(hex, 16);
        }
        return bytes;
    }
    public static void main(String[] args) {
        String hexString = "12345678ee";
        byte[] bytes = hexToBytes(hexString);
        System.out.println("16 进制字符串: " + hexString);
        System.out.println("转换后的 byte 数组: " + java.util.Arrays.toString(bytes)); // 输出: [18, 52, 86, 120, -18]
    }
}

总结与最佳实践

操作 推荐方法 优点 缺点
byte[] -> Hex Apache Commons Codec 稳定、高效、代码简洁 需要引入外部依赖
javax.xml.bind.DatatypeConverter 非常简单,无需额外依赖 已过时,Java 9+ 需要额外配置
手动实现 无依赖,适合学习或环境受限 代码稍长,性能可能不如库
Hex -> byte[] Apache Commons Codec 稳定、高效、代码简洁 需要引入外部依赖
javax.xml.bind.DatatypeConverter 非常简单,无需额外依赖 已过时,Java 9+ 需要额外配置
手动实现 无依赖,适合学习或环境受限 代码稍长,需要处理边界条件
  • 在绝大多数现代项目中,强烈推荐使用 Apache Commons Codec 库,它经过了充分测试,性能可靠,是业界的标准做法。
  • 如果你的项目不能引入任何外部库(某些面试场景或非常小的工具),或者你希望了解底层原理,那么手动实现是很好的选择。
  • 尽量避免使用 javax.xml.bind.DatatypeConverter,因为它已被标记为过时,未来可能会被完全移除。
Java 16进制byte数组如何互转?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇