将字节数组(byte[])转换为 16 进制字符串
这是最常见的操作之一,例如将哈希值、加密结果等字节数据以可读的字符串形式表示。

使用 javax.xml.bind.DatatypeConverter (JDK 1.6+)
这是最简单直接的方法,但需要注意它属于 javax.xml.bind 包,在 Java 9+ 中已被标记为 deprecated,且在 Java 11+ 中默认不可用(需要添加 --add-modules java.xml.bind 参数)。
import javax.xml.bind.DatatypeConverter;
public class HexUtil {
public static String bytesToHex(byte[] bytes) {
return DatatypeConverter.printHexBinary(bytes);
}
public static void main(String[] args) {
byte[] bytes = { (byte) 0xFF, 0x00, 0x7A, (byte) 0xCD };
String hexString = bytesToHex(bytes);
System.out.println(hexString); // 输出: FF007ACD
}
}
使用 Apache Commons Codec (推荐)
这是最常用和推荐的方法,因为它稳定、易用,且不依赖于 Java 内部可能被移除的 API。
需要在你的项目中添加依赖(Maven):
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version> <!-- 使用最新版本 -->
</dependency>
然后使用 Hex 工具类:

import org.apache.commons.codec.binary.Hex;
public class HexUtil {
public static String bytesToHex(byte[] bytes) {
return Hex.encodeHexString(bytes);
}
public static void main(String[] args) {
byte[] bytes = { (byte) 0xFF, 0x00, 0x7A, (byte) 0xCD };
String hexString = bytesToHex(bytes);
System.out.println(hexString); // 输出: ff007acd (默认小写)
// 如果需要大写
System.out.println(hexString.toUpperCase()); // 输出: FF007ACD
}
}
手动实现(不依赖任何库)
如果你不想引入外部依赖,可以手动实现一个转换函数,原理很简单:遍历字节数组的每一个字节,将其转换为两个 16 进制字符。
public class HexUtil {
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
if (bytes == null) {
return null;
}
char[] hexChars = new char[bytes.length * 2];
for (int i = 0; i < bytes.length; i++) {
int v = bytes[i] & 0xFF; // 将字节转换为无符号整型 (0-255)
hexChars[i * 2] = HEX_ARRAY[v >>> 4]; // 取高4位
hexChars[i * 2 + 1] = HEX_ARRAY[v & 0x0F]; // 取低4位
}
return new String(hexChars);
}
public static void main(String[] args) {
byte[] bytes = { (byte) 0xFF, 0x00, 0x7A, (byte) 0xCD };
String hexString = bytesToHex(bytes);
System.out.println(hexString); // 输出: FF007ACD
}
}
将 16 进制字符串转换为字节数组(byte[])
这是上述操作的逆过程,例如将从网络接收或从文件读取的 16 进制字符串还原为原始数据。
使用 javax.xml.bind.DatatypeConverter
import javax.xml.bind.DatatypeConverter;
public class HexUtil {
public static byte[] hexToBytes(String hexString) {
return DatatypeConverter.parseHexBinary(hexString);
}
public static void main(String[] args) {
String hexString = "FF007ACD";
byte[] bytes = hexToBytes(hexString);
// 打印字节数组内容
for (byte b : bytes) {
System.out.printf("%02X ", b); // 输出: FF 00 7A CD
}
}
}
使用 Apache Commons Codec
import org.apache.commons.codec.binary.Hex;
public class HexUtil {
public static byte[] hexToBytes(String hexString) {
return Hex.decodeHex(hexString.toCharArray());
}
public static void main(String[] args) {
String hexString = "FF007ACD";
byte[] bytes = hexToBytes(hexString);
// ...
}
}
手动实现
public class HexUtil {
public static byte[] hexToBytes(String hexString) {
if (hexString == null || hexString.length() % 2 != 0) {
throw new IllegalArgumentException("Invalid hex string");
}
int len = hexString.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
+ Character.digit(hexString.charAt(i+1), 16));
}
return data;
}
public static void main(String[] args) {
String hexString = "FF007ACD";
byte[] bytes = hexToBytes(hexString);
// ...
}
}
从 16 进制字符串中提取单个字节
如果你有一个长的 16 进制字符串,并想获取其中某个位置的字节,可以先将其转换为 byte[],然后通过索引访问。
public class HexUtil {
public static byte getByteFromHexString(String hexString, int index) {
if (index < 0 || index * 2 >= hexString.length()) {
throw new IndexOutOfBoundsException("Invalid index for hex string");
}
// 提取代表该字节的两个字符
String byteHex = hexString.substring(index * 2, index * 2 + 2);
return (byte) Integer.parseInt(byteHex, 16);
}
public static void main(String[] args) {
String longHexString = "A1B2C3D4E5F6";
// 获取第二个字节 (索引为1)
byte secondByte = getByteFromHexString(longHexString, 1);
System.out.printf("The second byte is: 0x%02X\n", secondByte); // 输出: 0xB2
}
}
在 Java 17 中使用 Integer.toHexString() 和 Integer.parseInt()
对于单个整数的转换,可以使用 Integer 类的内置方法。
整数转 16 进制字符串
int number = 255;
String hexString = Integer.toHexString(number);
System.out.println(hexString); // 输出: ff (小写)
// 如果需要固定宽度和前缀
String formattedHex = String.format("0x%08X", number);
System.out.println(formattedHex); // 输出: 0x000000FF
16 进制字符串转整数
String hexString = "FF"; int number = Integer.parseInt(hexString, 16); System.out.println(number); // 输出: 255 // 如果字符串有 "0x" 前缀,parseInt 无法直接处理 String hexWithPrefix = "0xFF"; // number = Integer.parseInt(hexWithPrefix, 16); // 会抛出 NumberFormatException // 正确做法是去掉前缀 number = Integer.parseInt(hexWithPrefix.substring(2), 16); System.out.println(number); // 输出: 255
总结与最佳实践
| 操作场景 | 推荐方法 | 备注 |
|---|---|---|
| 字节数组 ↔ 16进制字符串 | Apache Commons Codec | 最推荐,稳定、简洁、无依赖问题。 |
| 手动实现 | 适用于不能引入外部库的环境。 | |
javax.xml.bind.DatatypeConverter |
不推荐,未来可能被移除。 | |
| 单个整数 ↔ 16进制字符串 | Integer.parseInt() / Integer.toHexString() |
Java 内置方法,无需额外库。 |
| 处理带前缀的字符串 | String.substring() |
在使用 parseInt 前,手动去除 "0x" 或 "0X" 前缀。 |
对于任何与字节数据相关的 16 进制转换,强烈建议使用 Apache Commons Codec 库,它经过了充分测试,能正确处理各种边界情况,并且代码非常清晰易读。
