核心概念
- Byte (字节): 在 Java 中,
byte是一个 8 位有符号整数,其范围是-128到127。 - 16 进制 (Hexadecimal): 一种基数为 16 的数制系统,使用数字
0-9和字母a-f(或A-F) 来表示数值,一个 16 进制字符(如A)代表 4 个二进制位(即半字节,nibble),由于一个字节是 8 位,所以它恰好可以用两个 16 进制字符来表示。- 十进制
10-> 二进制00001010-> 16 进制0x0A或0A。 - 十进制
-128-> 二进制10000000-> 16 进制0x80。
- 十进制
将 byte 数组转换为 16 进制字符串
这是最常见的操作,byte 数组中的每个字节都需要被转换成两个 16 进制字符。

方法 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>
代码示例:

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:手动实现 (无需依赖,适合学习或简单场景)
如果你不想引入任何外部库,可以自己实现,核心思路是:
- 遍历 byte 数组。
- 对每个字节,使用
& 0xFF将其转换为无符号整数(0-255),避免负数问题。 - 使用
Integer.toHexString()将这个整数转换为 16 进制字符串。 - 判断转换后的字符串长度,如果只有 1 位(如
a),则在前面补一个0。 - 将所有字符拼接起来。
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:手动实现 (无需依赖,适合学习或简单场景)
- 检查 16 进制字符串的长度,如果不是偶数,则无法转换。
- 从头开始,每两个字符作为一个单元。
- 使用
Integer.parseInt(substring, 16)将这两个字符解析为一个整数。 - 将这个整数强制转换为
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,因为它已被标记为过时,未来可能会被完全移除。

